2017-08-31 31 views
2

構造体をコンストラクタで使用するC++コードをラップしようとしています。直接cythonからC++構造体コンストラクタを呼び出す

C++構造体:

typedef struct point_3d_t 
{ 
    double x; 
    double y; 
    double z; 

    point_3d_t(double x, double y, double z) 
     : x(x) 
     , y(y) 
     , z(z) 
     {} 

} point_3d; 

Cythonラッパー:

cdef extern from "./cppdar.hpp": 
    ctypedef struct point_3d: 
     point_3d(double, double, double) 
     double x; 
     double y; 
     double z; 

今、私はは(cythonファイル内から)cdef point_3d p1(v, v, v)のようなものを経由して、構造体を構築することができるようにを期待しましたしかし、私はCythonに提供されたコンストラクタを使う方法を理解できないようです。

私が試してみた:vが明示的cdef double v = 0ですが、どれも仕事

  • cdef point_3d p1(v, v, v)
  • cdef point_3d p1 = point_3d(v, v, v)
  • cdef point_3d p1(0, 0, 0)
  • cdef point_3d p1 = point_3d(0, 0, 0)

を。

...平野cdef point_3d p1p1.x = nnnnなどを使用して、それは迷惑なんだ、と私は、既定のコンストラクタを使用できないようにする必要があり、なぜ私は見ていない、私は思います。

問題を調べようとすると、クラスコンストラクタに関連した多くの混乱が発生しますが、これは役に立たないものです。

答えて

1

オクラホマので、答えはあなたがすべてので基本的に、cythonにコンストラクタ引数とC++オブジェクトを-割り当てるスタックすることはできませんですhttps://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs

はい、それは制限があります、それは パーサーよりも根本的な問題です。 C++でスタック割り当てられたオブジェクトの構造及び破壊が複雑その範囲に関連付けられ、そしてスコープ規則は、例えばPythonとCの 異なるされ、

if some_condition(): 
    x = Foo(1) 
else: 
    x = Foo(2, 3) 
return x.method() 

これは単にような表現できないと考えますC++で。逆に

if (some_other_condition()) { 
    Foo_with_RIAA foo(x) 
} 
... 

は、Pythonスコープ規則を「正しく」解釈しません。現在、すべての 変数がどの一部、C89 標準に従うことを(関数の先頭で宣言されているとして、

は、今では意味を作ることができる場合があるが、重要な コード生成の変更がなされなければなりませんC++モードでは、変数の宣言をインスタンス化 に遅らせるために があります(コード生成の簡略化のために、 が自動的に挿入されたCレベルの{}スコープを避けることを含む)。

このような複雑なオブジェクトを常にヒープに割り当てることができるため、この は重要な制限ではありません。

それはあなたが単には、多くの場合、デフォルトのコンストラクタを持たないラップクラスがないことを意味しているためこれは、余分なダブルプラス迷惑です。


恐ろしい、無良いハック回避策は、単純なC(++)関数のコンストラクタをラップし、次いでcython介しことを露出することです。

+0

私はあなたのworkroundがあなたを得ることを理解していませんか?私は思うに、あなたはまだデフォルトのコンストラクタが必要です。 – DavidW

+0

@DavidW - ええ、あなたはまだ構造体を構築して移動することができますが、デフォルトとしてインスタンス化し、メンバーを個別に設定するのが大変です。 –

+0

私はCythonが次に代入/移動代入を作成することができると信じています: 'cdef point_3d p'それから' p = point_3d(...) '。デフォルトコンストラクターと使用するコンストラクターについて、そのことを伝える必要があります。 – DavidW

関連する問題