详解python如何调用C/C++底层库与互相传值
前言
开发环境:
Centos7+Python3.5.1+QtCreator(只是使用QtCreator编译而已,并没有使用QT的任何库)
Python调用C/C++库,我现在能做到的有两种方式
1.extern“C”导出(互相传值比较麻烦,不建议使用这种方式):
将C/C++库做成和平常一样的DLL和或者.so,比如:
//.h文件 #include<Python.h> //.cpp文件 //C/C++my.so或者my.dll enter"C"voidprintHello() { std::cout<<"HelloWorld"<<std::endl; }
#Python importctypes fromctypesimport* loadso=ctypes.cdll.LoadLibrary mylib=loadso("./my.so") mylib.printHello() >>>Helloworld
代码解释:
my.so有一个C导出函数printHello()
importctypes :导入官方的一个库,顾名思义和C有关
loadso=ctypes.cdll.LoadLibrary :loadso表示加载库用的函数
mylib=loadso(“./my.so”)//或者loadso(“my.dll”) 加载my.so库
mylib.printHello():调用库函数
上述代码能正常输出:HelloWorld,但是他们没有互相传值
Python和C++互相传值
//.h文件 #include<Python.h> //.cpp文件 enter"C"intprintHello(constchar*str) { std::cout<<str<<std::endl; return1; }
那么Python的问题就来了
str=create_string_buffer(b"HelloWorld") #mylib.printHello("HelloWorld")这里死活就是显示:H,*(str+4)才是'e',*(str+8)是'l'依次类推 print(mylib.printHello(str)) >>>HelloWorld >>>1 #由于对Python不是特别的熟悉怎么也做不到显示C++返回的字符串,Python只能显示C++返回的字符串子能看到一个地址而已
2.Python扩展C/C++
不多说,直接上代码
//.h文件本来这是C++连接Mysql我只摘抄部分代#include<Python.h> //.cpp文件 //传递多个参数Python传过来的参数在args里面 PyObject*printfHello(PyObject*self,PyObject*args) { inti=0 constchar*str; if(!PyArg_ParseTuple(args,"i|s",&i,&str))//i表示整形s表示字符串 returnPyLong_FromLong(0); print("%d,%s",i,str); returnPy_BuildValue("s","OK");//向Python返回OK字符串 } //映射知道MFC的一看就懂 staticPyMethodDefMyMethods[]={ {"printfHello",printfHello,METH_VARARGS,//"printHello"中可调用的函数METH_VARARGS:带有参数METH_NOARGS:无参数 "print"},//说明 {"connect",connect,METH_VARARGS, "connectmysql"}, {NULL,NULL,0,NULL} }; staticPyObject*UtilError; //向Python中注册模块 staticstructPyModuleDefspammodule={ PyModuleDef_HEAD_INIT, "libMysqlUtil",//模块名字importlibMysqlUtil "C++ConnectMysql", -1, MyMethods };//PyInit_libMysqlUtil注意名字一定要PyInit_加上你的模块名字不然Pythonimport会提示没有定义PyInit_你的模块名字PyMODINIT_FUNCPyInit_libMysqlUtil(void){PyObject*m=nullptr;m=PyModule_Create(&spammodule); //m=Py_InitModule(....)Python2.7if(!m){returnm;}UtilError=PyErr_NewException("Util.error",NULL,NULL);Py_INCREF(UtilError);PyModule_AddObject(m,"error",UtilError);returnm;}
#python importlibMysqlUtil libMysqlUtil.printHello(1,"helloWorld") >>>1,helloWorld >>>OK
总结
到目前为止Python和C/C++互相通信,能适应大部分需求,结构体传值还没有研究,对于类,使用指针就行,C++里面是指针,在Python中会将指针转化成整形,Python将这个整形传给C++的时候使用PyArg_ParseTuple又将整形会变成类指针。
好了,以上就是本文的全部内容,希望本文的内容对大家学习python和C/C++能有所帮助。