C++ 和 Python 的相互调用

C++ 调用 Python (Python官方提供的实现方式)

    首先有一个Python函数

def PythonFunc(number):
    return number + 10;

我们期望在C++中使用的时候应该是类似下面这种

int UsePythonFunction(int num){
    int result;
    
    ///do something 

    return result;
}

这个do something 中就需要以下步骤:

  1. 要将python模块import进来
  2. 然后就应该把需要调用的Python函数对象创建出来
  3. 把C++参数转换成对应的Python中的参数
  4. 执行函数
  5. 将结果从Python对象转换成c++对象

根据以上的步骤可以写出下面的代码

int UsePythonFunction(int num){
    Py_Initialize();

    ///improt 对应模块 我这边的模块名字是python_function
    PyObject *pModule = PyImport_Import(PyString_FromString("python_function"));

    ///将对应的函数对象创建出来
    PyObject *pFunc = PyObject_GetAttrString(pModule, "PythonFunc");、

    ///这边是将参数转成Python版本
    PyObject *args = PyTuple_New(1);
    PyTuple_SetItem(args, 0, PyInt_FromLong(num));

    ///执行函数
    PyObject *res = PyObject_CallObject(pFunc, args);

    ///将结果转成C++版本
    int result = PyInt_AsLong(res);

    Py_Finalize();
    return result;
}
  • 从上面的代码可以看出,在C++ 中操纵Python对象的时候都是通过PyObject* 
  • C++中XXX类型转换成Python中YYY类型的时候,需要使用PyYYY_FromXXX,同理,从Python中YYY类型转成C++中XXX类型的时候,需要使用PyYYY_ASXXX
  • 创建Python元组的时候需要通过调用 PyTuple_New
  • 对元组赋值使用PyTuple_SetItem、

在Linux下使用下面命令进行编译链接。

gcc Test.cpp -o Test -I/usr/include/python2.7/ -lpython2.7

Python调用 C++ (Python官方提供的实现方式)

和之前的例子相同

这次我有一个C++的函数 在c_function_module.cpp中

int CFunction(int a) { 
          return a -= 10; 
} 

我想在Python以下方式来调用它

from c_function_module import CFunction
  
print CFunction(2);

这时候Python对象转C++对象的代码还是保存在C++文件中

  ///c_function_module.cpp
  #include <Python.h>                  
  
  int CFunction(int a) { 
          return a -= 10;                                                                             
  }                                                                                                   
                                                                                                      
  static PyObject * _CFunction(PyObject *self, PyObject *args)                                        
  {                                                                                                   
          int _args;                                                                                  
          int res;                                                                                    
                                                                                                      
          if (!PyArg_ParseTuple(args, "i", &_args))                                                   
                  return NULL;                                                                        
          res = CFunction(_args);                                                                     
          return PyLong_FromLong(res);                                                                
  }                                                                                                   
                                                                                                      
  static PyMethodDef CFunctionModuleMethods[] = {                                                     
          {                                                                                           
                  "CFunction",                                                                        
                  _CFunction,                                                                         
                  METH_VARARGS,                                                                       
                  ""                                                                                  
          },                                                                                          
          {NULL, NULL, 0, NULL}                                                                       
  };                                                                                                  
                                                                                                      
  PyMODINIT_FUNC initc_function_module(void) {                                                        
          (void) Py_InitModule("c_function_module", CFunctionModuleMethods);                          
  }                                                                             

解释下上面的一些东西:

  • CFunction 就是我们实际要调用的函数
  • _CFunction 成为包裹函数,它负责将Python对象转成C++对象,并调用对应函数,将结果转回Python 对象,PyArg_ParseTuple是将args按照后面的规则将参数转成_agrs,“i” 代表这第一个参数为Int,“is” 代表第一个参数为Int,第二个参数为字符串
  • CFunctionModuleMethods 成为导出表,这个表的每一项有4个参数:
在Python中需要调用的函数的名字
包裹函数
METH_VARARGS 代表变长参数
函数说明

导出表以{NULL, NULL, 0, NULL}结束

  • initc_function_module 这个是唯一 一个名字不能乱取的函数,这个函数名是init 加上 module名字构成,这边我的module名称为“c_function_module”,所以我的函数名字就是initc_function_module,

在linux中通过以下命令编译c++文件

gcc -fPIC -shared c_function_module.cpp -o c_function_module.so -I/usr/include/python2.7/ -lpython2.7

然后通过之前希望的方式在Python 中调用函数

还有一点,不能直接import整个模块,只能from模块import对应函数

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值