项目下载
cpp用cmake调用python方法的demo-C++文档类资源-CSDN下载
1. 使用
python3.6-config --ldflags 命令取得参数
#在控制台运行python3.6-config --ldflags 取得参数
#-L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
2. 新建一个project,名字是cppCallPythonFunc(范例里放在/home/hao/Documents下)
3. cmake里添加头文件和动态库位置
cmake_minimum_required(VERSION 3.19)
project(cppCallPythonFunc)
#set(CMAKE_CXX_STANDARD 14)
# 用locate Python.h 取得头文件的位置之后可以使用 #include <Python.h>
include_directories(
"/usr/include/python3.6m"
)
#在控制台运行python3.6-config --ldflags 取得参数
#-L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
# 添加动态库的位置
LINK_DIRECTORIES("/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu")
# LINK_DIRECTORIES("/usr/lib")
add_executable(runpy src/runpy.cpp src/runpy.h)
target_link_libraries(runpy -lpython3.6m)
4. 在项目下新建script文件夹,新建pyUtil.py
def multiply(a,b):
print("python multiply will compute", str(a), "times", str(b))
res=a*b
print("python multiply result:", res)
return res
5. 在项目下新建src文件夹,放入
runpy.h
#ifndef DEMO_RUNPY_H
#define DEMO_RUNPY_H
#include <Python.h>
void run_from_simple_str();
double run_with_return();
#endif //DEMO_RUNPY_H
runpy.cpp
//
// Created by hao on 2022/5/5.
//
#include "runpy.h"
double run_with_return();
void run_from_simple_str();
int main()
{
run_from_simple_str();
double result=run_with_return();
printf("Result of call: %f\n", result);
}
void run_from_simple_str() {
Py_Initialize();
// 如果无需接收返回值可以直接用PyRun_SimpleString
PyRun_SimpleString("import sys\n"
"sys.path.append('/home/hao/Documents/cppCallPythonFunc/script')\n"
"import pyUtil\n"
"print(pyUtil.multiply(1, 2))");
Py_Finalize();
}
double run_with_return() {
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *param_value1, *param_value2, *pValue_result;
double result;
//初始化
Py_Initialize();
// init_numpy();
if ( !Py_IsInitialized() )
{
fprintf(stderr, "Py_Initialize Failed ");
return -1;
}
// 导入文件目录
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/hao/Documents/cppCallPythonFunc/script')");
// PyRun_SimpleString("print(sys.path)");
const char * module_name="pyUtil";
// 优先使用这个方法取得module
pModule = PyImport_ImportModule(module_name);
// 以下2个方法是备用的
if (pModule == NULL)
pModule = PyImport_Import(PyUnicode_FromString(module_name));
if (pModule == NULL)
pModule = PyImport_Import(PyBytes_FromString(module_name));
if (pModule == NULL) {
PyErr_Print();
fprintf(stderr, "检查sys.path是否包含模块的路径");
return 1;
}
else{
// 从模块中获取函数
const char * func_name="multiply";
pFunc = PyObject_GetAttrString(pModule,func_name);
if (pFunc && PyCallable_Check(pFunc)) {
// 创建参数元组
// 2 个参数,输入第一个参数2.8,第二个参数7.2。7预期返回2.8*7.2=
pArgs = PyTuple_New(2);
param_value1=PyFloat_FromDouble(2.8);
param_value2=PyFloat_FromDouble(7.2);
// param_value2=PyLong_FromLong(7.2);
PyTuple_SetItem(pArgs, 0, param_value1);
PyTuple_SetItem(pArgs, 1, param_value2);
pValue_result = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue_result != NULL) {
// long result =PyLong_AsLong(pValue_result);
result = PyFloat_AsDouble(pValue_result);
// printf("Result of call: %f\n", result);
Py_DECREF(pValue_result);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
result=-1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find func");
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
// 反初始化
Py_Finalize();
return result;
}
|