Cracking open Python objects in C++

The answer is different for Panda3D 1.0.5 than it is for Panda3D 1.1.0 and later. I’ll answer assuming you are writing for 1.1.0.

There is a file in the Panda3D sources (specifically, in dtool/src/interrogatedb) called py_panda.h. Within this file is the structure definition:

struct Dtool_PyInstDef
{
        PyObject_HEAD
        void                 * _ptr_to_object;
        bool                   _memory_rules;
        unsigned long          _signiture;
        struct Dtool_PyTypedObject * _My_Type;
};

You can either include this header file, or duplicate this structure definition in your own sources (or at least the first two elements of the structure).

The key is that void *_ptr_to_object immediately follows PyObject_HEAD. Thus, you can retrieve the original C++ PNMImage object with code like this:


PNMImage *myImg = (PNMImage *)((Dtool_PyInstDef *)myImageWrapper)->_ptr_to_object;

Note that the above code performs no type checking; if you accidentally pass in, say, a string instead of a PNMImage, your program will certainly crash messily. The actual code generated for Panda does a bit more work than this simple cast, and will perform type checking properly; but it will be difficult to include that code in your own program without linking with Panda and possibly building within the Panda build environment.

Of course, building within the Panda build environment is not out of the question; the ppremake system in particular is designed to facilitate this. But I don’t know how far you meant to take this simple question. :slight_smile:

David