在开始编写程序之前,我们需对下面以下几个常用参数处理函数有个大概的了解:
1) Py_BuildValue()函数
作用:将C/C++类型类型的数据转变成PyObject*对象。
原型:PyAPI_FUNC(PyObject*) Py_BuildValue(const char *format, ...);(VC中复制过来的),有点类似与printf(format,…).
参数解释:format及转换格式,类似与C语言中%d,%f,后面的不定参数对应前面的格式,具体格式如下:
"s"(string) [char *] :将C字符串转换成Python对象,如果C字符串为空,返回NONE。
"s#"(string) [char *, int] :将C字符串和它的长度转换成Python对象,如果C字符串为空指针,长度忽略,返回NONE。
"z"(string or None) [char *] :作用同"s"。
"z#" (stringor None) [char *, int] :作用同"s#"。
"i"(integer) [int] :将一个C类型的int转换成Python int对象。
"b"(integer) [char] :作用同"i"。
"h"(integer) [short int] :作用同"i"。
"l"(integer) [long int] :将C类型的long转换成Pyhon中的int对象。
"c"(string of length 1) [char] :将C类型的char转换成长度为1的Python字符串对象。
"d"(float) [double] :将C类型的double转换成python中的浮点型对象。
"f"(float) [float] :作用同"d"。
"O&"(object) [converter, anything] :将任何数据类型通过转换函数转换成Python对象,这些数据作为转换函数的参数被调用并且返回一个新的Python对象,如果发生错误返回NULL。
"(items)"(tuple) [matching-items] :将一系列的C值转换成Python元组。
"[items]"(list) [matching-items] :将一系列的C值转换成Python列表。
"{items}"(dictionary) [matching-items] :将一系类的C值转换成Python的字典,每一对连续的C值将转换成一个键值对。
举例:
后面为PyObject的返回值
Py_BuildValue("")None
Py_BuildValue("i",123) 123
Py_BuildValue("iii",123, 456, 789) (123, 456, 789)
Py_BuildValue("s","hello") 'hello'
Py_BuildValue("ss","hello", "world") ('hello', 'world')
Py_BuildValue("s#","hello", 4) 'hell'
Py_BuildValue("()")()
Py_BuildValue("(i)",123) (123,)
Py_BuildValue("(ii)",123, 456) (123, 456)
Py_BuildValue("(i,i)",123, 456) (123, 456)
Py_BuildValue("[i,i]",123, 456) [123, 456] Py_BuildValue("{s:i,s:i}", "abc",123, "def", 456) {'abc': 123, 'def': 456}
Py_BuildValue("((ii)(ii))(ii)", 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))
2) PyArg_ParseTuple函数
作用:此函数其实相当于sscanf(str,format,…),是Py_BuildValue的逆过程,这个函数将PyObject参数转换成C/C++数据类型,传递的是指针,但这个函数与Py_BuildValue有点不同,这个函数只能解析Tuple元组,而Py_BuildValue函数可以生成元组,列表,字典等。
原型:PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *args, const char *format,...)
Args:一般为Python程序返回的元组。
Foramt:与Py_BulidValue类型,就不在累述咯。
3) 元组操作函数:
因为程序之间传递的参数,大多数为Tuple类型,所以有专门的函数来操作元组:
PyAPI_FUNC(PyObject *)PyTuple_New(Py_ssize_t size);
解释:新建一个参数列表(调试了下,发现其实是用链表实现的),size列表为长度的宽度
PyAPI_FUNC(Py_ssize_t)PyTuple_Size(PyObject *);
解释:获取该列表的大小
PyAPI_FUNC(PyObject *)PyTuple_GetItem(PyObject *, Py_ssize_t);
解释:获取该列表某位置的值
PyAPI_FUNC(int) PyTuple_SetItem(PyObject *,Py_ssize_t, PyObject *);
解释:设置该列表此位置的值。如PyTuple_SetItem(pyParams,1,Py_BuildValue("i",2));设置第2个位置的值为2的整数。
备注:对应的列表和字典也有对应的操作,详细见例子:
例子A:一个字符串参数和两个整数参数的例子
Demo.py的内容:
1
2
3
4
5def Hello(s): print("helloWord") print(s) def Add(a,b): print("{0}".format(a+b))
C++文件的内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include<Python27/python.h> int main() { Py_Initialize(); if(!Py_IsInitialized()) { printf("PythonInit failed!n"); return0; } PyObject*pModule = NULL; PyObject*pFunc = NULL; PyObject*pArg = NULL; pModule= PyImport_ImportModule("Demo"); pFunc= PyObject_GetAttrString(pModule,"Hello"); pArg= Py_BuildValue("(s)","function with arguement"); //一个字符串参数 PyEval_CallObject(pFunc,pArg); pFunc= PyObject_GetAttrString(pModule,"Add"); //两个整形的参数 pArg= Py_BuildValue("(i,i)",10,25); PyEval_CallObject(pFunc,pArg); Py_Finalize(); Return0; }
输出的结果为:
例子B:元组操作参数的例子
Demo.py的内容:
1
2def Add(a,b): print("{0}".format(a+b))
C++文件的内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include<Python27/python.h> int main() { Py_Initialize(); if(!Py_IsInitialized()) { printf("PythonInit failed!n"); return0; } PyObject*pModule = NULL; PyObject*pFunc = NULL; PyObject*pArg = NULL; pModule= PyImport_ImportModule("Demo"); pFunc= PyObject_GetAttrString(pModule,"Add"); //两个整形的参数 pArg= PyTuple_New(2); //确定Add函数两个参数 PyTuple_SetItem(pArg,0,Py_BuildValue("i",2)); //对参赛元组复制 PyTuple_SetItem(pArg,1,Py_BuildValue("i",3)); PyEval_CallObject(pFunc,pArg); Py_Finalize(); Return0; }
运行结果:
例子C:列表操作参数的例子
Demo.py的内容:
1
2
3
4def printList(l): print len(l) for var in l: print var
C++文件的内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include<Python27/python.h> int main() { Py_Initialize(); if(!Py_IsInitialized()) return0; PyObject*pModule = PyImport_ImportModule("Demo"); PyObject*pyFunc_printList = PyObject_GetAttrString(pModule,"printList"); if(pModule&& PyCallable_Check(pyFunc_printList)) { PyObject*pyParams = PyList_New(0); //初始化一个列表 PyList_Append(pyParams,Py_BuildValue("i",5));//列表添加元素值 PyList_Append(pyParams,Py_BuildValue("i",2)); PyList_Append(pyParams,Py_BuildValue("i",6)); PyList_Append(pyParams,Py_BuildValue("i",8)); PyObject*args = PyTuple_New(1); <span style="background-color: rgb(255, 102, 102);">//这步很关键:将列表转换成元组的一个元素后传递给Python程序</span> PyTuple_SetItem(args,0,pyParams); PyEval_CallObject(pyFunc_printList,args); } Py_Finalize(); Return0; }
运行结果:
例子D:传递类参数的例子
1
2
3
4
5class Person: def __init__(self, name): self.name = name def printName(self): print self.name
C++文件的内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include<Python27/python.h> int main() { Py_Initialize(); if(!Py_IsInitialized()) return0; PyObject*pModule = NULL; PyObject*pFunc = NULL; PyObject*pArg = NULL; PyObject*pClass = NULL; PyObject*pObject = NULL; pModule= PyImport_ImportModule("Demo"); pClass= PyObject_GetAttrString(pModule,"Person"); //先获取类名 pArg= PyTuple_New(1); PyTuple_SetItem(pArg,0,Py_BuildValue("s","Jacky")); pObject=PyEval_CallObject(pClass,pArg); //根据类名实例化对象 pFunc= PyObject_GetAttrString(pObject,"printName"); //根据对象得到成员函数 PyEval_CallObject(pFunc,NULL); Py_Finalize(); Return 0; }
运行结果:
例子E:Python程序返回参数的例子
1
2
3
4def mix(a,b): r1 = a + b r2 = a - b return (r1, r2)
C++文件的内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include<Python27/python.h> int main() { <span style="white-space:pre"> </span>Py_Initialize(); if(!Py_IsInitialized()) return 0; PyObject *pModule = PyImport_ImportModule("Demo"); PyObject *pyFunc_mix = PyObject_GetAttrString(pModule,"mix"); if(pModule && PyCallable_Check(pyFunc_mix)) { PyObject *pyParams = PyTuple_New(2); PyTuple_SetItem(pyParams,0,Py_BuildValue("i",5)); PyTuple_SetItem(pyParams,1,Py_BuildValue("i",2)); //PyTuple_SetItem(pyParams,2,Py_BuildValue("i",2)); int r1 = 0, r2 = 0; PyObject *pyValue = PyObject_CallObject(pyFunc_mix,pyParams); //调用函数返回结果 PyArg_ParseTuple(pyValue,"i|i",&r1,&r2);//分析返回的元组值 if(pyValue) { printf("%d %dn",r1,r2); } } Py_Finalize(); <span style="white-space:pre"> </span>return 0; }
运行结果:
最后
以上就是清爽灰狼最近收集整理的关于C++嵌入Python程序(二):参数传入及返回的全部内容,更多相关C++嵌入Python程序(二)内容请搜索靠谱客的其他文章。
发表评论 取消回复