Python调用C/C++动态库
程序员文章站
2022-07-14 09:40:38
...
两种方案
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
附录:
上一篇: Linux字符设备驱动之LCD驱动