7

以下で説明するように、あるクラスの c++ インスタンスが別のラップされたクラスのコンストラクターにフィードすることが期待される場合、誰かが Cython で c++ オブジェクトを操作する方法を提案できますか?

クラス PySession の pyx ファイルのメモを参照してください。これは、python PyConfigParams オブジェクトを引数として受け取り、そこから値を抽出して c++ ConfigParams オブジェクトを構築する必要があります。次に、ConfigParams オブジェクトを使用して、Session のコンストラクターをフィードします。

PyConfigParams オブジェクトによってラップされた ConfigParams c++ オブジェクトを、Session のコンストラクターに直接「注入」できる手順があれば理想的です。最初にそれを解体してから、新しい c++ オブジェクトを構築してコンストラクターにフィードする必要はありません。もちろん、これは機能します。ただし、信頼性が低いことは言うまでもなく、このソリューションを実装するのは面倒で残忍な方法です。

私は PyCapsule を認識していますが、c++ ヘッダーに触れる必要があるかもしれませんが、これは私にはできません。

これに関連しますが、別の質問があります: ConfigParams インスタンスを返すことによって C++ API の動作をシミュレートするために、ラップされたクラス (ここでは PySession としましょう) が必要な場合はどうすればよいですか? 逆に、C++ オブジェクトを分解して Python PyConfigParams を構築し、それを Python の世界の Python ユーザーに返す必要がありますか? どんな提案でも大歓迎です!ありがとうございました!

ConfigParams と Session という名前の 2 つの C++ クラスがあるとします。ConfigParams のインスタンスを使用して、Session クラスのコンストラクターをフィードします。

C++ クラス

ConfigParams クラス

// ConfigParams.h
#include <iostream> 
using namespace std; 
class ConfigParams 
{ 
  int parameter1; 
 public: 
  ConfigParams(int par1) { this->parameter1 = par1;} 
  int getPar1() { return this->parameter1; } 
};

セッションクラス

// 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 および pxd ファイル:

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 クラス

# 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() 
4

1 に答える 1

6

解決:

configparams.pxd モジュールで PyConfigParams を前方宣言します (これにより、session.pyx モジュールから呼び出すことができます)。

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

cdef class PyConfigParams:
    cdef ConfigParams* thisptr

session.pyx モジュールに PyConfigParams をインポートし、コンストラクターの引数をキャストします。これにより、逆参照する必要がある c++ オブジェクトへの PyConfigParams ポインターへのアクセスが許可されます。

# 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()
于 2012-05-22T18:15:58.753 に答える