Вопрос по c++, python – Конструкторы классов Cython и C ++

5

Может кто-нибудь предложить способ манипулирования объектами C ++ с помощью Cython, когда ожидается, что экземпляр c ++ одного класса будет подпитывать конструктор другого класса класс как описано ниже?

Пожалуйста, посмотрите на примечание к файлу pyx для класса PySession, которое принимает объект PyConfigParams Python в качестве аргумента, а затем необходимо извлечь значения из него, чтобы построить c ++ ConfigParams объект. затем объект ConfigParams используется для подачи конструктора сессии.

Было бы идеально иметь процедуру, которая позволила бы мне «вводить»; объект ConfigParams c ++, обернутый объектом PyConfigParams непосредственно в конструктор Session, без необходимости разбирать сначала это, а затем создание нового объекта c ++ для подачи в конструктор. Это работает, конечно. Тем не менее, это громоздкий, своего рода жестокий способ реализации этого решения, не говоря уже о ненадежности.

Я знаю о PyCapsule, однако он может потребовать прикосновения к заголовкам c ++, что я не могу сделать.

С этим связан, но другой вопрос: а что если мне понадобится завернутый класс (скажем, здесь PySession) для имитации поведения C ++ API, возвращая экземпляр ConfigParams? я должен был бы сделать перевернуть и разобрать объект c ++ для создания Python PyConfigParams что затем будет возвращено пользователю Python в мире Python? Любые предложения приветствуются! Спасибо!

Предположим, у меня есть два класса c ++ с именами ConfigParams и Session. Экземпляр ConfigParams используется для подачи конструктора Сессионный класс:

C++ classes ConfigParams class
// ConfigParams.h
#include <iostream> 
using namespace std; 
class ConfigParams 
{ 
  int parameter1; 
 public: 
  ConfigParams(int par1) { this->parameter1 = par1;} 
  int getPar1() { return this->parameter1; } 
};
Session class
// Session.h 
#include <iostream> 
using namespace std; 
#include "configparams.h" 
class Session 
{ 
  int sessionX; 
 public: 
  Session(ConfigParams parameters) { this->sessionX = parameters.getPar1(); } 
  void doSomething(); 
}; 

void Session::doSomething() 
{ 
  cout << "Session parameters set as: " << endl; 
  cout << "X = " << this->sessionX << endl; 
} 
Cython pyx and pxd files for the above classes: PyConfigParams
# configparams.pxd 
cdef extern from "configparams.h": 
    cppclass ConfigParams: 
        ConfigParams(int par1) 
        int getPar1() 

# configparams.pyx 
cdef class PyConfigParams: 
    cdef ConfigParams* thisptr 
    def __cinit__(self, i): 
        self.thisptr = new ConfigParams(<int> i) 
    def getPar1(self): 
        return self.thisptr.getPar1() 
PySession class
# session.pxd 
from configparams cimport * 
cdef extern from "session.h": 
    cdef cppclass Session: 
        Session(ConfigParams parameters) 
        void doSomething() 

# session.pyx
cdef class PySession: 
    cdef Session* thisptr 
    def __cinit__(self, pars): 
        # Note that here I have to extract the values 
        # from the pars (python PyConfigParams object) 
        # in order to build a c++ ConfigParams object 
        # which feeds the c ++ constructor of Session. 
        cdef ConfigParams* cpppargsptr = new ConfigParams(<int> pars.getPar1()) 
        self.thisptr = new Session(cpppargsptr[0]) 
    def doSomething(self): 
        self.thisptr.doSomething() 

Ваш Ответ

1   ответ
5

Вперед объявите PyConfigParams в модуле configparams.pxd (чтобы его можно было вызвать из модуля session.pyx)

# configparams.pxd                                                                                                                                                                                                                                            
cdef extern from "configparams.h":
    cppclass ConfigParams:
        ConfigParams(int par1)
        int getPar1()

cdef class PyConfigParams:
    cdef ConfigParams* thisptr

Импортируйте PyConfigParams в модуль session.pyx и приведите аргумент для конструктора, это предоставит доступ к указателю PyConfigParams на объект c ++, который необходимо разыменовать.

# session.pyx                                                                                                                                                                                                                                                 
from configparams cimport PyConfigParams
from cython.operator cimport dereference as deref

cdef class PySession:
    cdef Session* thisptr
    def __cinit__(self, PyConfigParams pars):
        self.thisptr = new Session(deref(pars.thisptr))
    def doSomething(self):
        self.thisptr.doSomething()

Похожие вопросы