C++调用 Python

fmms 13年前

采用Python脚本解释器进行脚本编译及脚本解释执行,而MT中主要采用C++编写,C++需要import py_compile模块进行脚本编译。

C++调用Python的实例如下:

/*      * test.cpp      *  Created on: 2010-12-12      *      Author: Handy_Zhou      */      #include <python2.6/Python.h>        #include <iostream>      #include <string>      void printDict(PyObject* obj) {          if (!PyDict_Check(obj))              return;          PyObject *k, *keys;          keys = PyDict_Keys(obj);          for (int i = 0; i < PyList_GET_SIZE(keys); i++) {              k = PyList_GET_ITEM(keys, i);              char* c_name = PyString_AsString(k);              printf("%s\n", c_name);          }      }      int main() {          Py_Initialize();          if (!Py_IsInitialized())              return -1;          PyRun_SimpleString("import sys");          PyRun_SimpleString("sys.path.append('./')");          //导入模块          PyObject* pModule = PyImport_ImportModule("testpy");          if (!pModule) {              printf("Cant open python file!\n");              return -1;          }          //模块的字典列表          PyObject* pDict = PyModule_GetDict(pModule);          if (!pDict) {              printf("Cant find dictionary.\n");              return -1;          }          //打印出来看一下          printDict(pDict);          //演示函数调用          PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");          PyObject_CallFunction(pFunHi, "s", "lhb");          Py_DECREF(pFunHi);          //演示构造一个Python对象,并调用Class的方法          //获取Second类          PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");          if (!pClassSecond) {              printf("Cant find second class.\n");              return -1;          }          //获取Person类          PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person");          if (!pClassPerson) {              printf("Cant find person class.\n");              return -1;          }          //构造Second的实例          PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);          if (!pInstanceSecond) {              printf("Cant create second instance.\n");              return -1;          }          //构造Person的实例          PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);          if (!pInstancePerson) {              printf("Cant find person instance.\n");              return -1;          }          //把person实例传入second的invoke方法          PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson);          //释放         Py_DECREF(pInstanceSecond);        Py_DECREF(pInstancePerson);        Py_DECREF(pClassSecond);        Py_DECREF(pClassPerson);        Py_DECREF(pModule);        Py_Finalize();          return 0;      } 

Python 源码

#!/usr/bin/python    # Filename: test.py      class Person:        def sayHi(self):            print 'hi'      class Second:        def invoke(self,obj):            obj.sayHi()      def sayhi(name):        print 'hi',name;  

执行

lhb@localhost:~/maplib/clib/pyc/invokepy$ ./test 

sayhi

__builtins__

__file__

__package__

Person

Second

__name__

__doc__

hi lhb

hi


我简单解释一下


这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。

Py_Initialize()和 Py_Finalize()是初始和销毁Python解释器

PyRun_SimpleString( "import sys" )导入sys,接着设置py文件的路径PyRun_SimpleString( "sys.path.append('./')" )

导入模块PyImport_ImportModule( "testpy" ),就是testpy.py模块。

获取模块字典列表,PyModule_GetDict(pModule),可以打印出来看一下如 void  printDict(PyObject* obj)函数

从字典中获取类的类型 PyDict_GetItemString(pDict, "Second" ),如函数也是这样获取的

创造类的实例 PyInstance_New(pClassSecond,NULL,NULL)

调用实例的方法PyObject_CallMethod(pInstanceSecond, "invoke" , "O" ,pInstancePerson)

整个流程就是这样的,并不复杂,如果要进一步研究可以参考:http://www.python.org/doc/


Extending and Embedding

Python/C API

比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。

C++转换成Python类型,Py_BuildValue()

http://www.python.org/doc/1.5.2p2/ext/buildValue.html


PyObject* pArgs=PyTuple_New( 1 ); //有几个参数,就是几

PyTuple_SetItem(pArgs, 0 ,Py_BuildValue( "i" , 3 ));  //初始第一个参数,数据类型是i,就是int,值是 3

返回值转换如,PyArg_ParseTuple,请参考

http://www.python.org/doc/1.5.2p2/ext/parseTuple.html

出处:
http://hi.baidu.com/zhouhanqing/blog/item/75b6134f2bddd91cb2de051a.html