Python calls C++

Method 1 (Foundation)

This method is called an extension to Python

int great_function(int a) {
    return a + 1;
}
Copy the code

Call this using Python

>>> from great_module import great_function 
>>> great_function(2)
3
Copy the code
// great_module.c

// Reference python's header file
#include <Python.h>

int great_function(int a) {
    return a + 1;
}

// Wrap functions, used to wrap functions that need to be converted to Python, preceded by an underscore.
static PyObject * _great_function(PyObject *self, PyObject *args)
{
    int _a;
    int res;

    // Check that the argument type is correct, and convert the Python argument to C
    if(! PyArg_ParseTuple(args,"i", &_a))
        return NULL;
    res = great_function(_a);
    return PyLong_FromLong(res);
}

// A list of methods defined for lookup in Python
static PyMethodDef GreateModuleMethods[] = {
    {
        "great_function",
        _great_function,
        METH_VARARGS,
        ""
    },
    {NULL.NULL.0.NULL}};// The method must be defined with init before the module name
PyMODINIT_FUNC initgreat_module(void) {(void) Py_InitModule("great_module", GreateModuleMethods);
}
Copy the code

Under Linux, GCC is used to compile:

$ gcc -fPic-shared great_module.c -o great_module.so -i /usr/include-python2.7/-lpython2.7Copy the code

GCC command line arguments:

  • -shared
    • Generates a shared object that can be connected to other objects into an executable
  • -fPIC
    • It is suitable for dynamic linking, avoids the limitation of global offset table size, and can only run on certain machines

Get great_module.so in the current directory, which can be used directly in Python.

Method 2 (SWIG)

SWIG : Simplified Wrapper and Interface Generator

Call c

Not only can be used in python, can also be used for other Java/perl/ruby/PHP/JavaScript/Go.

/* great_module.i */
%module great_module
%{
int great_function(int a) {
    return a + 1; %}}int great_function(int a);
Copy the code
  1. Defining module names is usually the same as file names.
  2. %{%} wraps the C code, which will be copied to mymodule_wrap.c intact
  3. List of function signatures to export. Just copy it from the original file
$ swig -c++ -python great_module.i
Copy the code

The corresponding great_module_wrap.c and great_module.py files are generated

To perform:

$ g++ -fPIC -shared great_class_wrap.cxx -o _great_class.so  -I/usr/include/python2.7/ -lpython2.7
Copy the code

Generate the corresponding _great_module.so file, which we can call directly from Python

from great_module import great_function

print great_function(9)

>>> 10
Copy the code

Call c + +

Define a header file, great_class.h

#ifndef GREAT_CLASS
#define GREAT_CLASS
class Great {
    private:
        int s;

    public:
        void setWall (int _s) {s = _s; };int getWall(a) {returns; }; };#endif
Copy the code

Create a great_class. I swig configuration file. Don’t write the swig definition again. SWIG is compiled with the -C ++ option to generate a CXX extension.

/* great_class.h */

%module great_class
%{
#include "great_class.h"
%}
%include "great_class.h"
Copy the code

Execute command:

$ swig -c++ -python great_class.i
Copy the code

Under Linux, the C++ compiler g++ is used

g++ -fPIC -shared great_class_wrap.cxx -o _great_class.so  -I/usr/include/python2.7/ -lpython2.7
Copy the code

Generate the corresponding _great_class.so file. You can now type directly in Python

import great_class
c = great_class.Great()
c.setWall(10)
print c.getWall()

>>> 10
Copy the code

reference

  • Zhihu by Jerry Jho
  • SWIG Users Manual Official document SWIG Users Manual
  • GCC command line option