欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

附录:

Python调用C/C++动态库

参考:https://www.cnblogs.com/apexchu/p/5015961.html

          https://www.cnblogs.com/yanzi-meng/p/8066944.html