4

I have successfully wrapped a C++ class, MyObject to Python using Swig.

class MyObject()
{
      public: 
        double i;
};

A MyObject can be created in Python like this:

import MyModule
m = MyModule.MyObject()

The important thing about the above lines is that behind the scenes, the MyObject object is created in the pyd module that is created from C++, and "somewhere", there is a new MyObject() call, returning a pointer to a MyObject object.

Further, the following Python script has a function that returns a Python MyObject, i.e:

import MyModule
def getMyObject():
    m = MyModule.MyObject()
    #... do something with m, e.g.
    m.i = 42
    return m

My actual use case is that I initialize the Python interpreter from a C++ application.

I am executing the Python function above,from within my C++ application, i.e.

PyObject *pValue = PyObject_CallObject(pFunc, NULL);  

where pFunc is a PyObject* that points to the getMyObject() python function. Code for setting up pFunc omitted for clarity. The returned value should hold a pointer to a MyObject "somewhere".

So question is, how, on the C++ side, do I go from the PyObject* pValue to a MyObject* pointer?

I do have a similar question open, see How to convert a returned Python dictionary to a C++ std::map<string, string>, but that question is more complex, as it involve the conversion from a Python dictionary, to a std class (std::map).

Having a user defined type, like MyObject, would perhaps be the first a user would want to learn to exchange. Curiously, I can't find a simple example showing how todo this.

I'm new to Swig but after doing some research it seem likely that one need to create a typemap?

Also, I'm using Embarcaderos C++ Builder, and can't use any C++11 and/or boost python libraries. Any hints?

Update The following code seem to properly unwrap the C++ object pointer:

        PyObject* p = python.callFunction(getPluginMetaDataF);
        PyObject* pThis = PyObject_GetAttrString(p, "this"); 
        unsigned long addr = PyLong_AsLong(pThis);
        MyObject* ptr = (MyObject*)(addr);
        cout << ptr->i; //Prints 42!

The above code seem to properly access the object. However, the life time of the object seem a little shaky, i.e. when is this object destroyed? After Py_Finalize() ??

Totte Karlsson
  • 1,261
  • 1
  • 20
  • 55
  • 1
    Here you can find an answer to your question, https://stackoverflow.com/questions/9040669/how-can-i-implement-a-c-class-in-python-to-be-called-by-c. It does a little more than what you - the class is extended in Python using the director pattern – Jens Munk Apr 25 '18 at 19:39

0 Answers0