Cython Class C++ 中的继承和嵌入

Cython Class Inheritance and embedding in C++

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

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

当我运行这个时,我收到以下信息:

<<< 标准输出 >>>

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

我知道这种在 C++ 中嵌入 Cython 的方法只适用于 Foo class,但是当我尝试从 FooSuper 扩展 Foo 时,FooSuper.__init__永远不会被调用。我知道这个问题一定来自我的初始化方法,但我已经将两个 __init__s 转换为 __cinit__s 没有任何变化。显然,段错误来自 FooSuper 的字段,根本没有被初始化。我也尝试过在 FooSuper class 中添加一个空心的 __cinit__(self, *args) ,没有任何变化。如果有人可以帮助我,我将不胜感激。谢谢。

因此,经过更多尝试后,我设法回答了我自己的问题。正如我所怀疑的那样,问题出在 super class 的初始化中。这是结果:

<<< 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