两种方案
1.利用ctypes.cdll.LoadLibrary直接在python中调用
C++动态库中函数的定义,关于动态库的生成请参考GCC生成及调用动态库和静态库
extern "C"{ string c_r(){ return "test0\n"; } char* c_t(){ return "test1\n"; } }
python中调用
import ctypes dl=ctypes.cdll.LoadLibrary lib=dl("./libreply.so")
因为类型转换问题,如果调用c_r(),会直接崩溃
>>> reply=lib.c_r >>> reply() [1] 2618 segmentation fault (core dumped) python
如果要调用c_t(),需要先设置函数的返回值类型
>>> reply=lib.c_t >>> reply.restype=ctypes.c_char_p >>> reply() 'test1\n' >>> print(reply()) test1
但是如果中文的话还需要再解码,新定义一个返回原值的函数
char* c_reply(char* inputStr){ if(inputStr==NULL) return "需要输入\n"; else return (char*)string(inputStr).c_str(); }
>>> print(reply("你好").decode("utf-8")) 你好
如果没有解码为utf-8的话不能正常显示中文
2.在C++文件中调用<Python.h>将要使用的函数和类等封装为python对象,然后作为一个模块供python使用
C++文件如下
#include<iostream> #include<stdlib.h> using namespace std; void printHello(){ cout<<"你好"<<endl; } int getInt(int i){ return i; } char* getCharArr(char* s){ return s; } string getStr(string s){ return s; } #include "/usr/include/python2.7/Python.h"//Python.h的位置到装python的地方找 static PyObject * Ext_printHello(PyObject *self, PyObject *args) { printHello(); return (PyObject*)Py_BuildValue(""); } static PyObject * Ext_getInt(PyObject *self, PyObject *args) { int num; if (!PyArg_ParseTuple(args, "i", &num)) return NULL; return (PyObject*)Py_BuildValue("i", getInt(num)); } static PyObject * Ext_getCharArr(PyObject *self, PyObject *args) { char* s; if (!PyArg_ParseTuple(args, "s", &s)) return NULL; return (PyObject*)Py_BuildValue("s", getCharArr(s)); } static PyObject * Ext_getStr(PyObject *self, PyObject *args) { string s; if (!PyArg_ParseTuple(args, "s", &s)) return NULL; return (PyObject*)Py_BuildValue("s", getStr(s)); } static PyMethodDef ExtMethods[] = { { "printHello", Ext_printHello, METH_VARARGS }, { "getInt", Ext_getInt, METH_VARARGS }, { "getCharArr", Ext_getCharArr, METH_VARARGS }, { "getStr",Ext_getStr,METH_VARARGS}, { NULL, NULL }, }; extern "C"{//extern "C"必须加,不然会找不到入口函数 void initExt() { Py_InitModule("Ext", ExtMethods); } }
编译为动态库Ext.so
python中调用,汉字仍然需要解码为utf-8
>>> import Ext >>> Ext.printHello() 你好 >>> Ext.getInt(99) 99 >>> Ext.getCharArr("你好\n") '\xe4\xbd\xa0\xe5\xa5\xbd\n' >>> print(Ext.getCharArr("你好\n").decode("utf-8")) 你好 >>>
&调用Ext.getStr()时还是崩溃,看样子是不支持string类型,只能用c_str()转化为字符串数字再返回
>>> Ext.getStr("hello") [1] 5347 segmentation fault (core dumped) python
附录: