我正在尝试将 Cython 类嵌入到 C++ 类中。鉴于项目的限制,不可能为此 C++ 类创建 Cython 包装器。并且由于 Cython 类中的方法数量和 Cython 类的长期继承,从类中完全删除方法并不是一个有吸引力的解决方案。我有必要创建一个 Cython 类实例并从 C++ 调用它的方法。但是,我似乎无法让它成为段错误。这是问题的示例:
<<< 文件:fooClass.pyx >>>
from math import sin
cdef public class Foo[object Foo, type fooType]:
cdef double a,b
def __cinit__(self, double a, double b):
self.a = a
self.b = b
cdef double bar(self, double c):
return sin(self.a*c)
cdef api double foobar(Foo foo, double d):
return foo.bar(d)
<<< 文件:Foo.cpp >>>
#include "fooClass_api.h"
#include <iostream>
int main(){
Py_Initialize();
import_fooClass();
Foo foo;
foo.a = 1.0;
foo.b = 10.0;
std::cout << foobar(&foo,5.0) << "\n";
Py_Finalize();
}
<<< 文件:setup.py >>>
from distutils.core import setup
from Cython.Build import cythonize
setup ( ext_modules = cythonize ("cyClass.pyx"))
我使用 python setup.py build_ext --inplace
构建并使用 g++ 编译。通过测试我知道 Py_Initialize()
和 import_fooClass
是成功的。我知道我在 foobar()
中打印了 foo.a
和 foo.b
的值,但是一旦我做了一个在 foobar()
中使用 Foo
对象调用,程序出现段错误。即使在 foobar()
中调用 foo.__dict__
或 foo.callable()
也会导致它出现段错误。更改 public
或 api
关键字已经生效,在 __init__
和 __cinit__
之间切换也没有效果。如果有人知道如何解决这个问题,我将不胜感激。我怀疑它与指针或滥用 Python C API 有关。非常感谢!
最佳答案
我设法解决了这个问题。根据 David W 所说(感谢 David!),我创建了另一个 cdef api
类作为构造函数的包装器,cdef api Foo buildFoo (double a, double b):
这将返回一个 Foo*
指针,这是 .pyx 文件中的 foobar(Foo foo, double d)
所需要的。生成的文件如下所示:
<<< 文件:fooClass.pyx >>>
from math import sin
cdef public class Foo[object Foo, type fooType]:
cdef double a,b
def __cinit__(self, double a, double b):
self.a = a
self.b = b
cdef double bar(self, double c):
return sin(self.a*c)
cdef api Foo buildFoo(double a, double b):
return Foo(a,b)
cdef api double foobar(Foo foo, double d):
return foo.bar(d)
<<< 文件:Foo.cpp >>>
#include "fooClass_api.h"
#include <iostream>
int main(){
Py_Initialize();
import_fooClass();
Foo *foo = buildFoo(10.0,5.0);
std::cout << foobar(foo,5.0) << "\n";
Py_Finalize();
}
使用相同的 setup.py
脚本。
运行此结果将 -0.262375
打印到标准输出,这是正确的结果。我希望使用这个想法的更复杂版本来替换我代码中对 boost::python 的一些调用,以提高性能。
关于python - 在 C++ 中嵌入 Cython 类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36455381/