20

I'm curious what the most flexible, most efficient, and most seamless method is for getting C++ and Python to talk to each other. The contenders seem to be Pybind11, Boost.Python, and neither (simply writing functions and wrappers as below).

using namespace boost::algorithm;
static PyObject* strtest(PyObject* self, PyObject* args)
{
    std::string s = "Boost C++ Libraries";
    to_upper(s);
    PyObject * python_val = Py_BuildValue("s", s.c_str());
    return python_val;
}


PyMODINIT_FUNC initmath_demo(void)
{
    static PyMethodDef methods[] = {
        "Test boost libraries" },
        { NULL, NULL, 0, NULL }

    };

    PyObject *m = Py_InitModule("math_demo", methods);
}
user2723494
  • 1,168
  • 2
  • 15
  • 26
  • 1
    Do you want to call python code from c++, call c++ code from python, or both? – pschill Apr 04 '18 at 14:28
  • At this stage, just call c++ from Python. Python calls c++, c++ performs some operation more efficiently, then passes the result back to python. – user2723494 Apr 04 '18 at 14:35
  • 9
    Both pybind11 and boost do a good job with creating the bindings. However, you want to think twice about introducing a large depency such as boost. If you only need a library for python bindings, go with pybind11, since it is much more lightweight. I also made good experiences with the cython library. The main difference between pybind11 and cython is that with pybind11 you write the bindings in c++, while in cython you write the bindings in a language similar to python. – pschill Apr 04 '18 at 14:52

2 Answers2

21

I would recommend PyBind11. I am using it for similar use-case where Python modules calls C++ to perform operations which are costlier and performance extensive. Boost Python is a richer library with size cost where as PyBind11 is header only and it supports STL which makes life easier to pass on basic data structure without writing any code! If you can wrap your calls to basic C function and primitive data types then Cpython would be the best!

ryadav
  • 456
  • 5
  • 11
15

We are using pybind11 in-house for something similar to what you describe (C++ module being accessed from Python). I am unwilling to pull in all the requirements of Boost, and pybind11 takes care of much of the "glue" normally necessary between C++ and Python. Things like converting exceptions are not readily thought of in many cases, but are handled nicely by pybind11.

In addition we write wrappers around our C++ internal classes, so that pybind11 can be pybind11 and our internal core engine can be C++. Translations are typically not that hard.

Personal experience with pybind11 is that "easy things are easy, hard things are still hard". Anything that is covered in the sample tutorial is quickly second nature, but things that aren't obvious usually take some digging to find a good way to do.

Still, all in all, very recommended. I would use it again for new projects in a heartbeat.

Joe Marley
  • 179
  • 6