详解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++能有所帮助。