栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

使用C++调用Python模块(Linux)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用C++调用Python模块(Linux)

工程配置

本文使用的项目构建工具为CMake,使用FindPython工具在CMake工程中找到Python库,注意CMake最低版本为3.12,参考:https://cmake.org/cmake/help/latest/module/FindPython.html

创建call_python.cpp文件,程序内容在下节详细说明。CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 3.12)
project(CallPython)

find_package (Python COMPonENTS Interpreter Development)
message(STATUS "Python_VERSION: ${Python_INCLUDE_DIRS}")
include_directories(
    ${PROJECT_SOURCE_DIR}/include
    ${Python_INCLUDE_DIRS} 
    )
# 生成目标文件
add_executable(call_python src/call_python.cpp)
# 链接库
target_link_libraries(call_python ${Python_LIBRARIES})
调用方法

使用C++调用Python脚本中的模块,一般需要经过如下几个步骤:

  1. 使用Py_Initialize()函数初始化Python解释器环境

  2. 添加.py脚本的路径,使用如下函数完成:

    // 添加.py的路径
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('脚本路径')");
    

    PyRun_SimpleString()函数也可以用来执行单条Python命令。

  3. 导入模块,使用Pyimport_importModule('模块名')完成:

    PyObject* pModule = Pyimport_importModule("模块名");
    
  4. 导入函数,使用PyObject_GetAttrString(模块指针, "函数名")来完成:

    PyObject* pFunc = PyObject_GetAttrString(pModule, "函数名");
    
  5. 构造函数的传入参数,要求以元组的形式传入,有两种方式进行构造,一种是使用Py_BuildValue()函数直接构造元组,使用方法如下:

    PyObject* args = Py_BuildValue("");
    

    其中()内可以指定参数格式,如下表所示:

    格式实际输入
    Py_BuildValue("")None
    Py_BuildValue(“i”, 123)123
    Py_BuildValue(“iii”, 123, 456, 789)123, 456, 789
    Py_BuildValue(“f”, 123.456)123.456
    Py_BuildValue(“fff”, 123.1, 456.2, 789.3)(123.1, 456.2, 789.3)
    Py_BuildValue(“s”, “hello”)‘hello’
    Py_BuildValue(“(s)”, “hello”)(‘hello’,)
    Py_BuildValue(“ss”, “hello”, “world”)(‘hello’, ‘world’)
    Py_BuildValue("(i)", 123)(123,)
    Py_BuildValue("((ii)(ii)) (ii)", 1, 2, 3, 4, 5, 6)(((1, 2), (3, 4)), (5, 6))
    Py_BuildValue("{s:i,s:i}", “abc”, 123, “def”, 456){‘abc’: 123, ‘def’: 456}

    注:实际输入中带()的格式才是元组形式,其余均不能直接作为参数传入到函数中。

    另一种方式是使用PyTuple_New()和PyTuple_SetItem(参数指针, index, value)函数间接构造元组:

    PyObject* args = PyTuple_New(2);
    PyTuple_SetItem(args, 0, Py_BuildValue("s", "python"));
    PyTuple_SetItem(args, 1, Py_BuildValue("i", 123);
    

    其中Py_BuildValue()使用方法见上表。

    如果传入参数是列表形式,则使用PyList_New()来构造一个列表,再将该列表加入到元组中即可

    // 构造一个列表,并添加成员
    PyObject* list = PyList_New(3);
    PyList_SetItem(list, 0, Py_BuildValue("i", 1));
    PyList_SetItem(list, 1, Py_BuildValue("i", 10));
    PyList_SetItem(list, 2, Py_BuildValue("i", 100));
    // 构造一个元组,将list加入到参数列表
    PyObject* args = PyTuple_New(1);
    PyTuple_SetItem(args, 0, list);
    
  6. 执行函数,使用PyObject_CallObject(函数指针, 参数指针)完成:

    PyObject_CallObject(pFunc, args);
    

    如果有返回值,则使用如下程序获取返回值:

    PyObject* pRet = PyObject_CallObject(pFunc, args);
    if (pRet)
    {
        long result = PyLong_AsLong(pRet); // 将返回值转换成long型  
        std::cout << "result:" << result << std::endl ;
    }
    
  7. 结束Python解释器:

    Py_Finalize();  
    
举例

创建一个.py文件,命名为calculator.py,内容如下:

def add(a, b):
    print(a + b)
    return a + b

def helloworld(s):
    print("hello " + s)

现在我们要调用该脚本中的add函数和helloworld函数,C++程序如下:

#include 
#include 

int main(int argc, char** argv){
    // 运行Python解释器
    Py_Initialize();
    
    // 添加.py的路径
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('')");
	
    
    
    // 导入模块
    PyObject* pModule = Pyimport_importModule("calculator");
    // 导入要运行的函数
    PyObject* pFunc = PyObject_GetAttrString(pModule, "add");
    // 构造传入参数    
    PyObject* args = PyTuple_New(2);
    PyTuple_SetItem(args, 0, Py_BuildValue("i", 1));
    PyTuple_SetItem(args, 1, Py_BuildValue("i", 10));
    // 运行函数,并获取返回值
    PyObject* pRet = PyObject_CallObject(pFunc, args);
    if (pRet)
    {
        long result = PyLong_AsLong(pRet); // 将返回值转换成long型  
        std::cout << "result:" << result << std::endl ;
    }
	
    
    
	// 导入函数
    pFunc = PyObject_GetAttrString(pModule, "helloworld");
    // 构造传入参数
    PyObject* str = Py_BuildValue("(s)", "python");
    // 执行函数
    PyObject_CallObject(pFunc, str);    
    // 终止Python解释器
    Py_Finalize();  

}

运行结果:

11
result:11
hello python
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/283432.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号