C++调用Python

  前两篇都是介绍Python调用C++的,换句话说,就是需要把C++封装成Python可以“理解”的类型。这篇,我打算说一下,C++怎么去调用Python脚本。其实这两者之间是相通的,就是需要可以互操作。按照惯例,先贴代码。
second.cpp

  1. #include <Python.h>
  2. #include <iostream>
  3. #include <string>
  4. void printDict(PyObject* obj)
  5. {
  6.     if( !PyDict_Check(obj))
  7.         return;
  8.     PyObject *k,*keys;
  9.     keys = PyDict_Keys(obj);
  10.     for(int i = 0; i < PyList_GET_SIZE(keys); i++)
  11.     {
  12.         k = PyList_GET_ITEM(keys, i);
  13.         char* c_name = PyString_AsString(k);
  14.         printf("%s/n",c_name);
  15.     }
  16. }
  17. int main()
  18. {
  19.     Py_Initialize();
  20.     if(!Py_IsInitialized())
  21.        return -1;
  22.     PyRun_SimpleString("import sys");
  23.     PyRun_SimpleString("sys.path.append('./')");
  24.     //导入模块
  25.     PyObject* pModule=PyImport_ImportModule("second");
  26.     if(!pModule)
  27.     {
  28.           printf("Cant open python file!/n");
  29.         return -1;
  30.     }
  31.     //模块的字典列表
  32.     PyObject* pDict = PyModule_GetDict(pModule);
  33.     if(!pDict)
  34.     {
  35.         printf("Cant find dictionary./n");
  36.         return -1;
  37.     }
  38.     //打印出来看一下
  39.     printDict(pDict);
  40.     //获取Second类
  41.     PyObject* pClassSecond = PyDict_GetItemString(pDict,"Second");
  42.     if( !pClassSecond )
  43.     {
  44.         printf("Cant find second class./n");
  45.         return -1;
  46.     }
  47.     //构造Second的实例
  48.     PyObject* pInstanceSecond = PyInstance_New(pClassSecond,NULL,NULL);
  49.     if( !pInstanceSecond)
  50.     {
  51.         printf("Cant create second instance./n");
  52.         return -1;
  53.     }
  54.     //获取Person类
  55.     PyObject* pClassPerson = PyDict_GetItemString(pDict,"Person");
  56.     if( !pClassPerson )
  57.     {
  58.         printf("Cant find person class./n");
  59.         return -1;
  60.     }
  61.     //构造Person的实例
  62.     PyObject* pInstancePerson = PyInstance_New(pClassPerson,NULL,NULL);
  63.     if( !pInstancePerson )
  64.     {
  65.         printf("Cant find person instance./n");
  66.         return -1;
  67.     }
  68.     PyObject_CallMethod(pInstanceSecond,"invoke","O",pInstancePerson);
  69.     Py_DECREF(pModule); //都需要释放,例子就不写了
  70.     Py_Finalize();
  71.     getchar();
  72.     return 0;
  73. }

second.py

  1. #!/usr/bin/python
  2. # Filename: second.py
  3. class Person:
  4.     def sayHi(self):
  5.         print 'hi'
  6. class Second:
  7.     def sayHello(self):
  8.         print 'hello'
  9.     def invoke(self,obj):
  10.         obj.sayHi()

我简单解释一下

  • 这个例子演示了,创建python中Person类的实例,并作为参数调用Second的方法。
  • Py_Initialize()和Py_Finalize()是初始和销毁Python解释器
  • PyRun_SimpleString("import sys")导入sys,接着设置py文件的路径PyRun_SimpleString("sys.path.append('./')")
  • 导入模块PyImport_ImportModule("second"),就是second.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/

比较特殊的是调用Python函数时,参数的传递,就是c++的类型,怎么转换成Python的类型;另外一个问题是,Python函数的返回值,怎么转换成C++中的类型。
C++转换成Python类型,Py_BuildValue()
http://www.python.org/doc/1.5.2p2/ext/buildValue.html

  1. PyObject* pArgs=PyTuple_New(1); //有几个参数,就是几
  2. PyTuple_SetItem(pArgs,0,Py_BuildValue("i",3));  //初始第一个参数,数据类型是i,就是int,值是3

返回值转换如,PyArg_ParseTuple,请参考
http://www.python.org/doc/1.5.2p2/ext/parseTuple.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值