本人因工作需要,近期研究了一下C++和Python的交互编程,看了一些资料,也踩了一些坑,总算是跑通了,为了让大家避免一些坑,也为了记录我学习的经历,在这里把我研究的过程与结果跟大家分享一下。
补充说明,该文章适用于有一定C++编程经验的人并初学Python的兄弟们,所以比如安装软件、配置环境这些操作,网上教程很多,就不给大家赘述了。
开发环境是VS2019、Python3.10
1、首先创建一个win32控制台C++工程
2、设置项目属性,配置Python的头文件包含目录,根据个人安装目录而定,我的目录是C:\Python310\include
3、配置Python库,配置附加库目录,同样根据个人安装目录而定,我的目录是C:\Python310\libs
4、添加附加依赖库,python3.lib、python310.lib、python310_d.lib这三个库(安装目录下没有python310_d.lib这个库,可以复制python310.lib然后改名为python310_d.lib)
1、添加头文件:#include
2、初始化Python库:Py_Initialize()
3、执行一句Python语句:PyRun_SimpleString(const char* s),例如:PyRun_SimpleString(“print(‘HelloWorld’)”)
4、加载模块:PyImport_ImportModule(const char* name),返回类型为PyObject的指针(PyObject是pthon在C++中所有类型的基类),指向所要加载的模块。例如:PyObject* Module = PyImport_ImportModule(“testpy”);
5、查找函数:PyObject_GetAttrString(PyObject*, const char*),第一个参数为函数所在的模块,第二个参数为函数名,返回类型也是PyObject的指针,指向所要查找的函数。例如:PyObject* Func = PyObject_GetAttrString(Module, “Greet”);
6、调用函数:PyObject_CallObject(PyObject* callable, PyObject* args),第一个参数为函数对象,第二个参数为调用该函数要传的参数集,参数集为python中的元组tuple。
7、释放资源:Py_Finalize()
def Greet():
print(“Hello World!”)
def Add(x, y):
return x + y
class PyCar:
def init(self, brand):
self.brand = brand
def Display(self):
print(self.brand)
Py_Initialize(); //初始化Python解释器
PyRun_SimpleString("print('Cpp call python!')");
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyRun_SimpleString("sys.path.append('../PythonScript')");
//加载模块
PyObject* Module = PyImport_ImportModule("PythonScript");
if (!Module)
{
std::cout << "加载模块失败!" << std::endl;
return -1;
}
//调用无参函数
{
//查找python函数
PyObject* Func1 = PyObject_GetAttrString(Module, "Greet");
if (!Func1)
{
std::cout << "没有找到对应函数" << std::endl;
return -1;
}
//调用python函数
PyObject_CallObject(Func1, nullptr);
}
//调用有参函数
{
PyObject* Func2 = PyObject_GetAttrString(Module, "Add");
if (!Func2)
{
std::cout << "没有找到对应函数" << std::endl;
return -1;
}
//定义函数参数
PyObject* Args1 = PyTuple_New(2); //另一种方法创建元组
PyObject* Arg1 = PyLong_FromLong(3);
PyObject* Arg2 = PyLong_FromLong(5);
PyTuple_SetItem(Args1, 0, Arg1);
PyTuple_SetItem(Args1, 1, Arg2);
PyObject* Ret1 = PyObject_CallObject(Func2, Args1);
if (Ret1)
{
long result = PyLong_AsLong(Ret1);
std::cout << "3 + 5 = " << result << std::endl;
}
PyObject* Args2 = Py_BuildValue("i, i", 30, 50); //构建tuple参数
PyObject* Ret2 = PyObject_CallObject(Func2, Args2);
if (Ret2)
{
std::cout << "30 + 50 = " << PyLong_AsLong(Ret2) << std::endl;
}
}
//访问Python类
{
//获取python类
PyObject* PyClass = PyObject_GetAttrString(Module, "PyCar");
PyObject* Args = PyTuple_New(1);
PyTuple_SetItem(Args, 0, Py_BuildValue("s", "Volvo"));
//生成一个对象
PyObject* Instance = PyObject_CallObject(PyClass, Args);
PyObject* Func = PyObject_GetAttrString(Instance, "Display"); //获取对象成员函数
PyObject_CallObject(Func, nullptr); //调用成员函数
}
//释放资源
Py_Finalize(); //关闭Python解释器
Cpp call python!
Hello World!
3 + 5 = 8
30 + 50 = 80
Volvo
http://www.cppblog.com/jacky2019/archive/2007/05/17/24269.html