Python calls C/C++ dynamic library

two options

1. Use ctypes.cdll.LoadLibrary to call directly in python

For the definition of functions in C++ dynamic library, please refer to GCC generation and call dynamic library and static library for the generation of dynamic library

extern "C"{
 string c_r(){
 	return "test0\n";
 }
 char* c_t(){
 	return "test1\n";
 }
 }
 

call in python

import ctypes
dl=ctypes.cdll.LoadLibrary
lib=dl("./libreply.so")

Because of the type conversion problem, if c_r() is called, it will crash directly

>>> reply=lib.c_r
>>> reply()
[1]    2618 segmentation fault (core dumped)  python

If you want to call c_t(), you need to set the return value type of the function first

>>> reply=lib.c_t
>>> reply.restype=ctypes.c_char_p
>>> reply()
'test1 \ n'
>>> print(reply())
test1

But if it is Chinese, it needs to be decoded again, and a new function that returns the original value is defined.

char* c_reply(char* inputStr){
	if(inputStr==NULL)
		return "requires input\n";
	else
     	return (char*)string(inputStr).c_str();
    
 }
>>> print(reply("你好").decode("utf-8"))
Hello

If it is not decoded to utf-8, it cannot display Chinese normally


2. Call <Python.h> in the C++ file to encapsulate the functions and classes to be used as python objects, and then use them as a module for python

The C++ file is as follows

#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"//The location of Python.h goes to the place where python is installed
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" must be added, otherwise the entry function will not be found
void initExt()  
{  
    Py_InitModule("Ext", ExtMethods);  
}
}

Compile as dynamic library Ext.so

Called in python, Chinese characters still need to be decoded to utf-8

>>> import Ext
>>> Ext.printHello()
Hello
>>> Ext.getInt(99)
99
>>> Ext.getCharArr("Hello\n")
'\xe4\xbd\xa0\xe5\xa5\xbd\n'
>>> print(Ext.getCharArr("你好\n").decode("utf-8"))
Hello

>>>

& still crashes when calling Ext.getStr(), it seems that the string type is not supported, and can only be converted to a string number with c_str() and then returned

>>> Ext.getStr("hello")
[1]    5347 segmentation fault (core dumped)  python

appendix:


Reference: https://www.cnblogs.com/apexchu/p/5015961.html

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325602952&siteId=291194637