0

I have a Linux C++ dynamic library, which is required to pass a compound structure to python, and receive result structure from python to be transferred up to caller application.

To get the python interpreter "alive" after library API function returns back to caller application, I decided to use singleton class (using getInstance...)

For C/Python API I'm (trying to...) using pybind11 embedded module mechanism

Question is how to connect the embedded module within the singleton class, simply meaning how to invoke it from there (also with passed arguments)?

Looked at "calling-embedded-function-in-class-method-using-pybind11", but it don't answer my question

GM1
  • 380
  • 3
  • 14
  • 1
    I'm gonna offer a word of caution - having your library spin up a Python interpreter seems convenient now, but it will become a foot gun once you want to use your library elsewhere. If your code needs Python, I'd strongly recommend writing your C++ code as pure C++, and then write Python bindings, and then have your entry point be Python only. It'll save you a lot of headaches in the future (I've been hurt by this pattern in other tools, and I've seen large projects go through headaches b/c of this design). – eacousineau Mar 08 '19 at 13:33
  • I agree, easiest way is to pass information through files (E.g. json) and have a single connection point... – GM1 Aug 29 '19 at 16:28

1 Answers1

3

Seems I found the answer

Although I'm working on a Linux project, I find this link:Embedding Python in a C++ project with Visual Studio, with its sample project, very educational,

and looking back at pybind11 embedded documentation, section 13.4 at the PDF, shows it is simply to do so:

Include "py::module" member at C++ class which would be initialized with py::module::import("module_name");

and then call the C'tor etc. using it

such as:

// class member
py::module mModule;

and

//initialization
mModule = py::module::import("module_name");
mModule .attr("initialize").call(mArg1, mArg2);

Since this is a singleton class within a library, rather than regular example of main(), for the interpreter lifetime, I find it better to use:

py::initialize_interpreter();
{
//call py code...    
}

and then call py::finalize_interpreter(); at the destruction of this instance

rather than, regular py::scoped_interpreter guard{}; which finishes its lifetime at the end of the scope

GM1
  • 380
  • 3
  • 14