1

I have a program written in c++ that functions on it's own, however we want to make it accessible to Python. Specifically, we have several functions that are more efficient in c++, but we do a lot of other things with the output using Python scripts. I don't want to rewrite the whole of main() in Python as we make use of Boost's root finding algorithms and other functionalities that'd be a pain to do in Python.

Is it possible to add Python binding to these functions while keeping the c++ main()? I've never done Python binding before, but I've looked at Boost.python since we're already using Boost. Most of the examples use c++ functions/classes in a hpp file and embed them into a python program, which isn't exactly what we want.

What we want is to keep our c++ program as a standalone so it can run as it is if users want, and also allow users to call these functions from a Python program. Being able to use the same Makefile and exe would be great. We don't really want to make a separate c++ library containing the bound functions; we're not interested in making a pythonic version of the code, merely allowing access to these useful functions.

Thanks

Kari
  • 21
  • 4
  • 1
    Possible duplicate of [Calling C/C++ from python?](http://stackoverflow.com/questions/145270/calling-c-c-from-python) – Emil Sierżęga Jul 27 '16 at 21:00
  • You probably need GObject Introspection library. – Arunmu Jul 27 '16 at 21:24
  • At least with Cython it is possible to have call chain like 'C++ main -> C function implemented in cython -> python code -> python module implemented in cython -> C++ code...'. It is probably possible with Boost.python also. – J.J. Hakala Jul 27 '16 at 21:28
  • It is worth pointing out that it is usually considered good practice for the C/C++ main to do very little other than parsing the parameters and then calling the actual processing with the parsed results - this makes what you are considering doing, or any bindings, much easier. – Steve Barnes Jul 28 '16 at 05:46

1 Answers1

1

We have an extensive c++ library which we made available to python through use of a python wrapper class which calls an interface that we defined in boost python.

One python class handles all the queries in a pythonic manner, by calling a python extension module written in c++ with boost python. The python extension executes c++ code, so it can link and use anything from the original library.

You said your c++ is an executable, though. Why can't you use system calls to launch a shell process? You can do that in any language, including python. What I thought was you want to access individual functions, which means you need all your functions in a static library.

You build your c++ exe normally, linking the common code. You make a "boost python extension module" which links the common code, and can be imported by a python script. And of course a unit test executable, which links and tests the common code. My preference is that the common code be a stand-alone static lib (use -fPic if there's a posix gcc build).

Kenny Ostrom
  • 5,639
  • 2
  • 21
  • 30
  • It might be worth mentioning the possibility of using a shared library, (.dll/.so), as a possibility as well as a static library. – Steve Barnes Jul 28 '16 at 05:42
  • The python extension module is (and must be) a shared library (.pyd/.so). The underlying code library has to be compatibile with that (-fPic) but making it also shared means you have to distribute it and not have any version/interface mismatches. Risk with no benefit. – Kenny Ostrom Jul 28 '16 at 13:58
  • Please note that the answer above, mentions linking a __static__ library to the python code - this is wrong. You also have the possibility of building a static library for a C++ executable and a shared library to bundle into a wheel with the python interface. – Steve Barnes Jul 28 '16 at 17:32
  • I'm willing to correct any errors, but I think we just have a miscommunication. Python doesn't link, but it can import a shared library (python extension module). When this shared library was built from c++, other shared or static libraries may have been linked (and that's where your c++ code library came in). – Kenny Ostrom Jul 29 '16 at 13:46
  • Above states "...and link the static library..." then ".. link the same c++ library ..." it should read " import a DLL built with the source of the same C++ library ..." – Steve Barnes Jul 29 '16 at 14:20
  • That is for building the original c++ executable. – Kenny Ostrom Jul 29 '16 at 14:35
  • Also, building multiple projects from the same SOURCE files is bad. That's the whole point of a library -- build once. – Kenny Ostrom Jul 29 '16 at 14:58
  • Building multiple outputs from a single set of source files is generally considered good especially it you can use make tools and keep the options the same for compiling both, so C++s -> .obj happens once and objs -> lib -> exe plus objs -> dll -> wheel. Your original answer still reads that python is using the same [static] library. – Steve Barnes Jul 29 '16 at 15:37
  • 1
    I edited my answer to separate my recommendation from the points we agree on. And I do grant that makefile achieves the same thing of building the source once. – Kenny Ostrom Jul 29 '16 at 16:25