Home > Backend Development > Python Tutorial > Detailed explanation of how Python calls C++ programs

Detailed explanation of how Python calls C++ programs

高洛峰
Release: 2017-02-20 10:28:28
Original
1465 people have browsed it

Preface

Everyone knows that the advantages of Python are high development efficiency and ease of use, while C++ has high operating efficiency. The two can complement each other, whether in Python If you embed C++ code in a project, or use Python to implement peripheral functions in a C++ project, you may encounter the need for Python to call C++ modules. Here are several basic methods for exporting C++ code into Python interfaces. Let’s learn together. .

Original export

The Python interpreter is implemented in C, so as long as our C++ data structure can be understood by Python , in theory, it can be called directly. We implement test1.cpp as follows

#include <Python.h>

int Add(int x, int y)
{
 return x + y;
}

int Del(int x, int y)
{
 return x - y;
}

PyObject* WrappAdd(PyObject* self, PyObject* args)
{
 int x, y;
 if (!PyArg_ParseTuple(args, "ii", &x, &y))
 {
  return NULL;
 }
 return Py_BuildValue("i", Add(x, y));
}

PyObject* WrappDel(PyObject* self, PyObject* args)
{
 int x, y;
 if (!PyArg_ParseTuple(args, "ii", &x, &y))
 {
  return NULL;
 }
 return Py_BuildValue("i", Del(x, y));
}
static PyMethodDef test_methods[] = {
 {"Add", WrappAdd, METH_VARARGS, "something"},
 {"Del", WrappDel, METH_VARARGS, "something"},
 {NULL, NULL}
};

extern "C"
void inittest1()
{
 Py_InitModule("test1", test_methods);
}
Copy after login

The compilation command is as follows

g++ -fPIC -shared test1.cpp -I/usr/include/python2.6 -o test1.so
Copy after login

Run Python interpretation The test is as follows

>>> import test1
>>> test1.Add(1,2)
3
Copy after login

There are a few points to note here

  1. If the name of the generated dynamic library is test1, the source file must have the inittest1 function, and the first parameter of Py_InitModule must be "test1", otherwise the Python import module will fail

  2. If it is a cpp source file, the inittest1 function must be modified with extern "C". If it is a c source file, it is not required. The reason is that the Python interpreter will look for functions such as initxxx when importing libraries, and C and C++ encode function symbols differently. C++ will consider the function length and parameter type when encoding function symbols. Specifically, you can use nm test1.soView function symbols, the c++filt tool can decode the function prototype through symbols

Achieved through boost

We use the same example as above to implement test2.cpp as follows

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;

int Add(const int x, const int y)
{
 return x + y;
}

int Del(const int x, const int y)
{
 return x - y;
}

BOOST_PYTHON_MODULE(test2)
{
 def("Add", Add);
 def("Del", Del);
}
Copy after login

The parameters of BOOST_PYTHON_MODULE are The module name to be exported

The compilation command is as follows

g++ test2.cpp -fPIC -shared -o test2.so -I/usr/include/python2.6 -I/usr/local/include -L/usr/local/lib -lboost_python
Copy after login

Note: is required during compilation Specify the paths to the boost header files and libraries, here they are /usr/local/include and /usr/local/lib

or export the module through setup.py

#!/usr/bin/env python
from distutils.core import setup
from distutils.extension import Extension

setup(name="PackageName",
 ext_modules=[
  Extension("test2", ["test2.cpp"],
  libraries = ["boost_python"])
 ])
Copy after login

The first parameter of Extension is the module name, and the second parameter is the file name

Execute the following command

python setup.py build
Copy after login

The build directory will be generated at this time, find test2.so inside, and enter the same level directory, verify as follows

>>> import test2
>>> test2.Add(1,2)
3
>>> test2.Del(1,2)
-1
Copy after login

Export class

test3.cpp is implemented as follows

#include <boost/python.hpp>
using namespace boost::python;

class Test
{
public:
 int Add(const int x, const int y)
 {
  return x + y;
 }

 int Del(const int x, const int y)
 {
  return x - y;
 }
};

BOOST_PYTHON_MODULE(test3)
{
 class_<Test>("Test")
  .def("Add", &Test::Add)
  .def("Del", &Test::Del);
}
Copy after login

##Note: How to use .def in BOOST_PYTHON_MODULE Somewhat similar to Python's syntax, it is equivalent to

class_<Test>("Test").def("Add", &Test::Add);
class_<Test>("Test").def("Del", &Test::Del);
Copy after login

The compilation command is as follows

g++ test3.cpp -fPIC -shared -o test3.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
Copy after login

Test As follows

>>> import test3
>>> test = test3.Test()
>>> test.Add(1,2)
3
>>> test.Del(1,2)
-1
Copy after login

Export variable parameter function

test4.cpp is implemented as follows

#include <boost/python.hpp>
using namespace boost::python;

class Test
{
public:
 int Add(const int x, const int y, const int z = 100)
 {
  return x + y + z;
 }
};

int Del(const int x, const int y, const int z = 100)
{
 return x - y - z;
}

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Add_member_overloads, Add, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(Del_overloads, Del, 2, 3)

BOOST_PYTHON_MODULE(test4)
{
 class_<Test>("Test")
  .def("Add", &Test::Add, Add_member_overloads(args("x", "y", "z"), "something"));
 def("Del", Del, Del_overloads(args("x", "y", "z"), "something"));
}
Copy after login

Both the Add and Del functions here use default parameters. Del is an ordinary function and Add is a class member function. Different macros are called here. Macros The last two parameters represent the minimum number of parameters and the maximum number of parameters of the function respectively

The compilation command is as follows

g++ test4.cpp -fPIC -shared -o test4.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
Copy after login

The test is as follows

>>> import test4
>>> test = test4.Test()
>>> print test.Add(1,2)
103
>>> print test.Add(1,2,z=3)
6
>>> print test4.Del(1,2)
-1
>>> print test4.Del(1,2,z=3)
-1
Copy after login

##Export an interface with Python objects
Since it is exported as a Python interface , the caller will inevitably use Python-specific data structures, such as tuple, list, dict. Since the original ecological method is too troublesome, only the usage of boost is recorded here. Assume that the following Python function functions are to be implemented

def Square(list_a)
{
 return [x * x for x in list_a]
}
Copy after login

That is, calculate the square of each element of the incoming list and return the result of list type

The code is as follows

#include <boost/python.hpp>

boost::python::list Square(boost::python::list& data)
{
 boost::python::list ret;
 for (int i = 0; i < len(data); ++i)
 {
  ret.append(data[i] * data[i]);
 }

 return ret;
}

BOOST_PYTHON_MODULE(test5)
{
 def("Square", Square);
}
Copy after login

The compilation command is as follows

g++ test5.cpp -fPIC -shared -o test5.so -I/usr/include/python2.6 -I/usr/local/include/boost -L/usr/local/lib -lboost_python
Copy after login

The test is as follows

>>> import test5
>>> test5.Square([1,2,3])
[1, 4, 9]
Copy after login

boost implementation Here are the data types of

boost::python::tuple

, boost::python::list, boost::python::dict, how to use them It is basically consistent with Python. For specific methods, you can view boost/python/tuple.hpp and other corresponding files in the boost header file. Another commonly used function is

boost::python::make_tuple( )

, the usage method is as follows

boost::python::tuple(int a, int b, int c)
{
 return boost::python::make_tuple(a, b, c);
}
Copy after login

For more detailed explanations on how Python calls C++ programs, please pay attention to the PHP Chinese website for related articles!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template