dream/ 三月 29, 2018/ C/C++, python/ 0评论

两种方案

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

 

附录:

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

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

点击数:92

Share this Post

说点什么

avatar
300
  订阅  
提醒