Cython类继承和嵌入在C ++中

时间:2016-04-11 14:06:10

标签: python c++ inheritance cython

我需要在一些C ++代码中嵌入我的Cython类,并且我无法使继承工作,并且在尝试访问基类的字段时不断出现分段错误。由于项目的限制,无法包装C ++类或从Cython代码中删除类。以下是我的问题的一个提炼示例:

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

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

当我运行时,我收到以下内容:

&LT;&LT;&LT; std out&gt;&gt;&gt;

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

我知道这种在C ++中嵌入Cython的方法只适用于Foo类,但是当我尝试从Foo扩展FooSuper时,永远不会调用FooSuper.__init__。我知道这个问题必须来自我的初始化方法,但是我已经将__init__转换为__cinit__而没有任何变化。很明显,段错误来自FooSuper未完全初始化的字段。我还尝试在__cinit__(self, *args)类中添加空心FooSuper而不做任何更改。如果有人能帮助我,我会非常感激。谢谢。

1 个答案:

答案 0 :(得分:0)

经过多次尝试后,我设法回答了自己的问题。正如我所怀疑的那样,问题在于超类的初始化。结果如下:

&LT;&LT;&LT; fooClass.pyx&gt;&gt;&gt;

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)

&LT;&LT;&LT; foo.cc&gt;&gt;&gt;

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

这编译并运行没有问题产生:

&LT;&LT;&LT; std out&gt;&gt;&gt;

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