Python调用C程序https://blog.csdn.net/qq_22751305/article/details/105361916?spm=1001.2014.3001.5501
C/C++调用Python函数
包含常规数值的传入传出,数组的传入传出。
针对模块导入,返回空指针的问题,也有说明,见代码注释。
以win10为例。默认已经安装好Python环境。注意:需配置PYTHONHOME和PYTHONPATH环境变量,否则运行时可能会报错。
在vs2015上配置Python,这个比较简单。步骤如下:
1. 系统环境变量PATH中追加路径:
D:\ProgramData\Anaconda3\envs\py39;
D:\ProgramData\Anaconda3\envs\py39\Library\bin
2. 在工程属性表中添加include目录和库目录,添加附加依赖项:
至此,环境配置好了。
C调用Python函数
python代码如下python_test.py:
import cv2
import numpy as np
def list_test(array, N):
print('test list')
print(array)
print(N)
return [1.3,2,3,4]
def add(a,b):
print('a+b=')
return a+b
def show_img():
im = cv2.imread('qq.jpg')
cv2.imshow('qq',im)
cv2.waitKey(1)
C/C++代码如下,见注释。
#include<iostream>
#include "opencv2/opencv.hpp"
//#include "D:/ProgramData/Anaconda3/envs/py39/include/python.h"
//#pragma comment(lib, "D:\\ProgramData\\Anaconda3\\envs\\py39\\libs\\python39.lib")
//若在编译器设置了include和lib路径以上两行可以转化为
#include<Python.h>
int main()
{
// 初始化python
Py_Initialize();
if (!Py_IsInitialized())
{
std::cout << "python initialized failed\n";
}
//添加python_test.py文件所在路径
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('D:/workspace/C_python/C_python/')");
//导入模块,不带后缀
//若python_test.py文件路径不对、python环境不对、python_test.py中存在错误,
// 都会导致pModule为空指针。
PyObject* pModule = PyImport_ImportModule("python_test");
if (!pModule)
{
std::cout << "Python get module failed." << std::endl;
}
PyObject* pDict = PyModule_GetDict(pModule);
if (!pDict)
{
std::cout << "Python get dict failed." << std::endl;
}
PyObject *pFunc = PyDict_GetItemString(pDict, "show_img");
PyObject_CallObject(pFunc,NULL);
pFunc = PyDict_GetItemString(pDict, "add");
//参数进栈
PyObject *pArgs = PyTuple_New(2);
//下面的是重点了,从c/c++传参数到Python中时需要用到一个函数,原型为
//PyObject* Py_BuildValue(char *format,……)
//类似c的printf,但格式不同。常见的格式有
//s 字符串
//i 整形变量
//f 浮点型
//o Python对象
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 3));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4));
//调用Python函数
PyObject *pRetVal = PyObject_CallObject(pFunc, pArgs);
printf("function return value: %d\n", PyLong_AsLong(pRetVal));
printf("function return value: %f\n", PyFloat_AsDouble(pRetVal));
// C向python函数传入数组
PyObject *pList = PyList_New(100);
for (int i = 0; i < 100; i++)
{
PyList_SetItem(pList, i, Py_BuildValue("i", i));
}
PyTuple_SetItem(pArgs, 0, pList);
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 100));
pFunc = PyDict_GetItemString(pDict, "list_test");
PyObject* pRes = PyObject_CallObject(pFunc, pArgs);
// 获取返回值list,并解析
int N = PyList_Size(pRes);
printf("the res N: %d\n", N);
for (int i = 0; i < N; i++)
{
printf("%f, ",PyFloat_AsDouble( PyList_GetItem(pRes, i)));
}
Py_Finalize(); //释放资源
system("pause");
return 0;
}