小结c++中使用python时的互调

来源:互联网 发布:ug编程教程百度云盘 编辑:程序博客网 时间:2024/04/29 18:35

  1. C++ 调用python

    C++调用python接口,对于c++方来说,需要python提供其c接口;对于python来说,需要理解c++参数。

    Python作为一个脚本语言,首先要在c中初始化生成解析器:

    Py_Initialize()

    一个Python脚本对应一个包,接下来将需要的脚本加载到解析器:

    PyObject *pModule = PyImport_Import();

    获取脚本中需要调用的方法对象:

    PyObject *pFunc = PyObject_GetAttrString(pModule,funName);

    调用方法:

    PyObject *pValue = PyObject_CallObject(pFun, pParams);

     

    可以看到python返回值都是指针,可以推出2点:(1python虚拟机运行在c进程之中;(2)虚拟机和c共享了同一进程空间数据,对象由谁释放?由python虚拟机在释放。根据谁拥有谁释放, python方法中产生的对象,得由它自己来释放。

     

     

  2. Python 回调c++

    这里说的python回调C++,是在上面一的基础之上的。比如,C++调用了python某个接口,而这个接口需要通过回调C++的方式打日志。

    Python如何理解C++接口?C++对象转成pythonmodule

    server = Py_InitModule("server", server_methods);

    PyObject_SetAttrString(server, "Myclass",PyDict_New());

     

    之后,python脚本中通过引用该包,就可以像使用普通包一样使用了。

     

    下面是我们想暴露的一个函数: char const* greet(unsigned x){static char const* const msgs[] = { "hello","Boost.Python","world!" }; if (x > 2)throw std::range_error("greet: index out of range"); return msgs[x];} 用Python的C API和标准C++来包装这个函数,我们需要像这样: extern "C" // 所有Python交互都使用C链接和调用习惯{// 处理参数/结果转换和检查的包装层PyObject* greet_wrap(PyObject* args,PyObject * keywords){int x;if (PyArg_ParseTuple(args,"i",&x)) // 取出/检查参数{char const* result = greet(x); // 调用被包装的函数return PyString_FromString(result); // 结果转换成Python}return 0; // 发生了错误} // 待包装函数表,函数用这个模块来暴露static PyMethodDef methods[] = {{ "greet",greet_wrap,METH_VARARGS,"return one of 3 parts of a greeting" },{ NULL,NULL,0,NULL } // sentinel}; // 模块初始化函数DL_EXPORT init_hello(){(void) Py_InitModule("hello",methods); // 添加成员函数(method)到模块}} 
  3. 关于Py_INCREF() Py_DECREF()

    关于Py_INCREF() Py_DECREF()C中何时使用,这个比较麻烦参考

    http://blog.sina.com.cn/s/blog_7d9e524a0100x6sx.html

    我的理解是这样:

    1.C调用python接口返回的对象(PyObject_CallObject返回),都是新生成的,只有C中会用,因此用完之后需要Py_DECREF().

    2.通过Pyxx_Getxx()取到的对象,说明是已经存在的对象,存在共用的情况,因此需要Py_INCREF(),用完之后Py_DECREF().

    3.对于借用的返回很容易出问题,可以统一按2处理。

    4.对于python回调C时,传入的对象指针,不用管,因为C回调任然在Python方法之类,而python是自动管理内存的。

     


0 0
原创粉丝点击