Создание объекта C ++ в Python и передача его указателя обратно в C ++? - PullRequest
0 голосов
/ 24 апреля 2018

Я успешно упаковал класс C ++, MyObject в Python, используя Swig.

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

MyObject может быть создан в Python следующим образом:

import MyModule
m = MyModule.MyObject()

Важная вещь о вышеприведенных строках заключается в том, что за кулисами объект MyObject создается в модуле pyd, который создается из C ++, и «где-то» существует вызов new MyObject (), возвращая указатель на объект MyObject.

Кроме того, в следующем скрипте Python есть функция, которая возвращает объект Python MyObject, то есть:

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

В моем случае я инициализирую интерпретатор Python из приложения C ++ .

Я выполняю приведенную выше функцию Python из моего приложения на C ++, т.е.

PyObject *pValue = PyObject_CallObject(pFunc, NULL);  

где pFunc - это PyObject *, который указывает на функцию Python getMyObject (). Код для настройки pFunc опущен для ясности. Возвращаемое значение должно содержать указатель на MyObject «где-то».

Итак, вопрос в том, как на стороне C ++ перейти от PyObject * pValue к указателю MyObject *?

У меня есть похожий открытый вопрос, см. Как преобразовать возвращенный словарь Python в C ++ std :: map , но этот вопрос более сложный, поскольку включает преобразование из словаря Python в класс std (std :: map).

Наличие пользовательского типа, такого как MyObject, возможно, будет первым, кого пользователь захочет научиться обмениваться. Любопытно, что я не могу найти простой пример, показывающий, как это сделать.

Я новичок в Swig, но после некоторого исследования кажется вероятным, что нужно создать typemap ?

Кроме того, я использую Embarcaderos C ++ Builder и не могу использовать любые библиотеки C ++ 11 и / или boost Python. Есть намеки?

Обновление Следующий код, кажется, правильно разворачивает указатель объекта C ++:

        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!

Код выше, похоже, правильно обращается к объекту. Однако время жизни объекта кажется немного шатким, то есть когда этот объект разрушается? После Py_Finalize () ??

...