前一节配置完了环境后只是简单测试了一下,这一节要通过实例讲解来了解里面的api
#include <Python.h>
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
Py_Initialize();
if (!Py_IsInitialized())//检测是否已初始化,成功返回0
{
cout << "初始化失败!!" << endl;
system("pause");
return -1;
}
//PyRun_SimpleString实际上是一个宏,执行一段Python代码。
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pModule,*pDict,*pFunc,*pArgs;
pModule = PyImport_ImportModule("pytest");
if (!pModule)
{
cout << "找不到testpy,或打开失败!" << endl;
system("pause");
return -1;
}
pDict = PyModule_GetDict(pModule);//相当于Python模块对象的__dict__属性,得到模块名称空间下的字典对象。
if (!pDict)
{
return -1;
}
pFunc = PyDict_GetItemString(pDict, "Add");
// pFunc=PyObject_GetAttrString(pModule, "Add"); //也可以使用该函数得到函数对象,这样连__dic__属性都不需要获取,更简单
if (!pFunc || !PyCallable_Check(pFunc))
{
cout << "找不到add函数" << endl;
system("pause");
return -1;
}
pArgs = PyTuple_New(2);//参数为元组长度,也就是参数个数
/*int PyTuple_SetItem( PyObject *p, Py_ssize_t pos, PyObject *o)
其参数含义如下所示。
p:所进行操作的元组。
pos:所添加项的位置索引。
o:所添加的项值。*/
//Py_BuildValue把C++的变量转换成一个Python对象。当需要从C++传递变量到Python时,就会使用这个函数
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 3));//i相当于c里面的%d
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4));
// 调用Python函数
PyObject_CallObject(pFunc, pArgs);
Py_Finalize();//清理工作
system("pause");
return 0;
}
注:对于Py_BuildValue里的参数使用见这里
更多可能用到的函数,见这里
pytest代码:
def Add(a,b):
print ("in python function add")
print ("a = " + str(a))
print ("b = " + str(b))
print ("ret = " + str(a+b) )
常用函数以及调用流程:
1.初始化Py_Initialize()以及检测是否已经初始化的Py_IsInitialized()的函数,成功初始化函数的返回值为0
2.PyRun_SimpleString 执行一段python代码,类似与调用了一下python环境,比如PyRun_SimpleString("print('hello')"); 就会输出hello字样
3.PyImport_ImportModule导入模块,可以是自己写的模块,也可以是系统模块,如test.py 就 PyImport_ImportModule("test")
4.PyObject_GetAttrString获得一个函数对象,参数一为导入模块函数的返回值,参数2为要获得的函数对象的名称。用PyCallable_Check检测是否成功获得
5.PyTuple_New(size_t),里面的参数为调用元组的元素个数,其实就等同于调用的函数的参数个数。
6.PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "hanliangwei")); 将函数参数放入元组中
7.PyObject_CallObject 调用函数,参数1为导入的函数对象的,参数2为需要传入的元组
8.PyArg_ParseTuple 如果函数有返回值,调用该函数获得函数的返回值,参数1为PyObject_CallObject的返回值,参数2为格式化格式,格式与上面Py_BuildValue的格式相同,后面再接上需要用来保存返回值的变量
9.最后调用Py_Finalize();做一些清理工作