Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expose C++ functions in python and embed python in C++

Tags:

c++

python

My app have some events, each event can have some actions. These actions is implemented in C++. I want to expose those core functions to python and use python to write the action. The advantage is I can modify actions without recompile. For example:

CppClass o;

// --- this is a action----
o.f1();
o.f2();
// ------------------------

use python to script the action:

def action1(o):
    o.f1()
    o.f2()

In c++, use interpreter to run this script, find action1 and call it with a PyObject which convert from c++ object. Actually, I have not expose f1() & f2() to python, I just use python to regroup the definition of action, all function is running by c++ binary code. Notice that I have not to give a definition of f1() & f2() in python.

The problem is: how I expose global functions? such as:

def action2():
    gf1()
    gf2()

boost::python can expose function, but it is different, it need compile a DLL file and the main() is belong to python script. Of course I can make global functions to be a class static member, but I just want to know. Notice that I HAVE TO give a definition of gf1() & gf2() in python.

Jython can do this easily: just import Xxx in python code and call Xxx.gf1() is ok. But in cython, how I define gf1() in python? This is a kind of extension, but extension requires Xxx be compiled ahead. It seems only way is make gf() into a class?

like image 392
jean Avatar asked Jan 30 '12 02:01

jean


2 Answers

Solved. boost::python's doc is really poor...

For example: expose function

void ff(int x, int y)
{
    std::cout<<x<<" "<<y<<std::endl;
}

to python:

import hello
def foo(x, y)
    hello.ff(x, y)

you need to expose it as a module:

BOOST_PYTHON_MODULE(hello)
{
    boost::python::def("ff", ff, boost::python::arg("x"), boost::python::arg("y"));
}

But this still is not a 'global function', so expose it to python's main scope:

BOOST_PYTHON_MODULE(__main__)
{
    boost::python::def("ff", ff, boost::python::arg("x"), boost::python::arg("y"));
}

then you can write:

def foo(x, y)
   ff(x, y)
like image 146
jean Avatar answered Oct 06 '22 09:10

jean


You might also want to have a look at Cython.

Cython's main function is to translate (a subset of) Python code to C or C++ code to build native code Python extensions. As a consequence, it allows interfacing C/C++ code with a very terse and Python-ish syntax.

Cython's user guide provides a good example of how to call a simple C++ class from Python: http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#declaring-a-c-class-interface

In addition to creating extensions, Cython can also generate C/C++ code that embeds the Python interpreter, so you do not need to build and ship an external DLL. See details at: http://wiki.cython.org/EmbeddingCython

like image 40
Riccardo Murri Avatar answered Oct 06 '22 09:10

Riccardo Murri