2016-04-11 26 views
0

Bazı C++ kodlarında Cython sınıflarımı gömmem gerekiyor ve temel sınıfın alanlarına erişmeye çalışırken, çalışmanın kalıtımını alamıyorum ve bölümlere ayırma hataları almaya devam edemiyorum. Projenin kısıtlamaları nedeniyle C++ sınıfını sarmak veya sınıfları Cython kodundan çıkarmak mümkün değildir.Cython Sınıf Kalıtım ve gömülme C++

< < < dosya: 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) 

< < < dosyası: 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() 
} 

İşte benim sorunun distile örneğidir Bunu çalıştırıyorum, aşağıdaki iletiyi alırım:

< < < std dışarı >>>

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

C++ Cython gömme için bu yaklaşım sadece Foo sınıfı ile çalıştığını biliyorum ama FooSuper.__init__ asla denir, FooSuper den Foo uzatmak çalıştığınızda. Bu sorunun başlatım yöntemimden gelmesi gerektiğini biliyorum, ancak hiçbir değişiklik yapmadan __init__ s değerini __cinit__ s'ye dönüştürdüm. Açıkçası, segfault hiç başlatılmamış olan FooSuper alanlarından geliyor. Ayrıca hiçbir değişiklik yapmadan __cinit__(self, *args) değerini FooSuper sınıfına eklemeyi denedim. Birisi bana yardım edebilirse çok minnettar olurum. Teşekkürler.

cevap

0

Bazı daha fazla denemeden sonra kendi sorumu yanıtlamayı başardım. Sorun şüphe ettiğim gibi süper sınıfın başlatılmasıydı.

< < < 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 >>> Bu derler ve sorun boyun eğmeden çalışır

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

:

İşte sonuç

< < < std dışarı >>>

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