2016-04-11 44 views
0

CythonクラスをいくつかのC++コードに埋め込む必要があり、継承を機能させることができず、基本クラスのフィールドにアクセスしようとするとセグメンテーションフォルトが発生し続けることがあります。プロジェクトの制約のため、C++クラスをラップしたり、クラスをCythonコードから削除することはできません。Cythonクラス継承とC++への埋め込み

< < <ファイル:fooClass.pyx >>>

from math import sin 

cdef public class FooSuper[object FooSuper, type FooSuperType]: 
    def __init__ (self, a): 
     print "FooSuper.__init__ START" 
     self.a = a 
     print "FooSuper.__init__ END" 

cdef public class Foo(FooSuper)[object Foo, type FooType]: 
    def __init (self, a, b): 
     print "Foo.__init__ START" 
     FooSuper.__init__(self, a) 
     self.b = b 
     print "Foo.__init__ END" 

    cdef double bar (self, double c): 
     return sin(self.a * c) 

cdef public Foo buildFoo (double a, double b): 
    print "buildFoo(a,b) START" 
    return Foo(a,b) 

cdef public double foobar (Foo foo, double c): 
    print "foobar(Foo,c) START" 
    return foo.bar(d) 

< < <ファイル:foo.cc >>>

#include <Python.h> 
#include "fooClass.h" 
#include <iostream> 

int main(){ 
    Py_Initialize(); 
    initfooClass(); 
    Foo *foo = buildFoo(1.0, 2.0); 
    std::cout << foobar(foo, 3.0) << std::endl; 
    Py_Finalize() 
} 

ここに私の問題の蒸留例があります私はこれを実行し、私は以下を受け取る:

< < < STDアウト>>>

buildFoo(a,b) 
Foo.__init__ START 
foobar(Foo,d) 
Segmentation fault 

は、私はC++でCythonを埋め込むには、このアプローチは、単にはFooクラスで動作することを知って、私はFooSuper.__init__が呼び出されることはありません、FooSuperからFooを拡張しようとします。私はこの問題が私の初期化方法から来なければならないことを知っていますが、私は__init____cinit__に変更せずに両方とも変換しました。明らかに、segfaultはFooSuperのフィールドからまったく初期化されていません。また、FooSuperクラスに中空の__cinit__(self, *args)を追加してみましたが、変更はありません。誰かが私を助けることができれば、私は非常に感謝します。ありがとう。

答えて

0

私は自分の質問に答えることができました。問題は、私が疑ったように、スーパークラスの初期化です。ここでの結果は次のとおりです。

< < < fooClass.pyx >>>

from math import sin 

cdef public class FooSuper[object FooSuper, type FooSuperType]: 

    cdef double a 

    #This is needed to initialize the underlying C struct of the super class 
    cdef __cinit__(self, *argv): 
     print "FooSuper.__cinit___()" 

    def __init__(self, a): 
     print "FooSuper.__init__() START" 
     self.a = a 
     print "FooSuper.__init__() END" 

cdef public class Foo(FooSuper) [object Foo, type FooType]: 
    cdef double b 

    def __init__(self, a, b): 
     print "Foo.__init__() START" 
     FooSuper.__init__(self, a) 
     print "Foo.__init__() END" 

    cdef double bar (self, double c): 
     return sin(self.a*c) 

cdef public Foo buildFoo (double a, double b): 
    print "buildFoo(a,b)" 
    return Foo(a,b) 

cdef public double foobar(Foo foo, double c): 
    print "foobar(Foo, c)" 
    return foo.foobar(c) 

< < < foo.cc >>>

#include <Python.h> 
#include "fooClass.h" 
#include <iostream> 

int main(){ 
    Py_Initialize(); 
    initfooClass(); 
    Foo *foo = buildFoo(1.0, 2.0); 
    std::cout << foobar(foo, 3.0) << std::endl; 
    Py_Finalize() 
} 

これは、コンパイルし、降伏問題なく動作します:

< < <標準出力>>>

buildFoo(a,b) 
FooSuper.__cinit__() 
Foo.__init__() START 
FooSuper.__init__() START 
FooSuper.__init__() END 
Foo.__init__() END 
foobar(Foo,c) 
0.14112