我需要在一些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
而不做任何更改。如果有人能帮助我,我会非常感激。谢谢。
答案 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