I have certain amount of math-heavy code that I need to implement in C++ for performance reasons. I do that using boost.python to create new modules which I import to Python. Everything works well until I include panda libraries into my project.
For example, I have code which makes no reference to Panda but in my linker settings I have Panda libs as additional dependencies and that causes Python to output;
SystemError: dynamic module not initialized properly
whenever I try to import my module.
I find that very odd because I realize, that when Panda objects are referenced in my code I should call some initializations and function to make everything square with Python’s internals which in Panda case is something I have no clue about so, this is what I want to ask:
-How to use Panda’s objects in C++ and build modules with boost.python which would import properly in Python?
This could be a Python version conflict. Panda is compiled to link against a particular version of Python (even if you’re not using its Python interfaces at the moment). If you link with Panda, and also link with a different version of Python, those two Python libraries will step on each other.
I can think of two solutions: (1) ensure you are using the precise same version of Python that Panda is linked with, or (2) recompile a version of Panda yourself that doesn’t link with Python at all.
Make sure you are not linking your app with pystub. This is a library that we ship with Panda that is designed to be linked into apps that do not themselves link with Python; it provides dummy stubs for all of the Python API functions that Panda has hooks into. It is necessary to avoid link errors in your non-Python program.
Since you are linking with Python, though, you should certainly not also link with pystub, and doing so will cause harm to Python.
The class LPoint3f in C++ is renamed to Point3 in Python.
Of course, they are not precisely the same class, because Point3 is a Python wrapper around the C++ LPoint3f. (See the Subclassing section of the manual for a more detailed explanation of this process.)
Still, it is possible to convert from one to the other without too much trouble. There are examples in the forums, as well as throughout the Panda source code. Is this what you’re asking for?
Note that ownership of the Python object is not passed into the C++ object, so you are still responsible for freeing (or dereferencing) the Python object after this call.
Note that ownership of the C++ object is passed into the Python object, so it should be allocated via “new” and not freed.
Also, for the record, the above operations are for LPoint3f, which does not inherit from TypedObject or ReferenceCount. For classes that do inherit from these base classes, the operations are slightly different.
The PyObject “steals” a reference to the C++ object when you pass it into DTool_CreatePyInstanceTyped(), so you have to compensate for this by explicitly calling:
Hmm, it works fine for me. I just pasted in your code (minus the boost stuff) into a file that’s processed by interrogate, and I can call getGeom() from Python and retrieve a perfectly valid Geom, a pair of back-to-back red triangles.
Can you return other kinds of PyObjects via Boost? Short of decrementing the Python reference count on your py_geom object, I’m not sure that Boost could do that much destructive here. There might be some other problem.
I’d try to narrow it down by (a) returning a standard Python object, like a PyList or something, and then (b) returning a simple Panda object like a Point3.
Everything works well with such simple Panda objects. I have a function which takes Point3 parameter, converts it to LPoint3f, does some math and returns Point3 and it works without problems.