在C++中嵌入Cython类方法
Embedding Cython Class Methods in C++
我正试图在C++类中嵌入一个Cython类。考虑到项目的限制,为这个C++类创建Cython包装器是不可能的。由于Cython类中方法的数量和Cython类长时间的继承,从类中完全删除该方法并不是一个有吸引力的解决方案。我有必要创建一个Cython类实例,并从C++调用它的方法。然而,我似乎不能让它不出错。这里有一个问题的例子:
<lt<文件: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)
<lt<文件: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();
}
<lt<文件: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()
,也会导致其segfault。更改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)
所需要的。生成的文件如下所示:
<lt<文件: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)
<lt<文件: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
打印到stdout,这是正确的结果。我希望使用这个想法的一个更复杂的版本来替换在我的代码中对boost::python的一些调用,以提高性能。
在一个更复杂的设置中使用了前面提到的技术并反复获得segfault之后,这里是我使用的另一种方法。关键区别在于pyx
文件中的api
和public
关键字,以及如何在foo.cpp
中包括和使用类。
<lt<文件: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 public Foo buildFoo(double a, double b):
return Foo(a,b)
cdef public double foobar(Foo foo, double d):
return foo.bar(d)
<lt<文件:Foo.cpp>>
#include <Python.h>
#include "fooClass.h"
#include <iostream>
int main(){
Py_Initialize();
initfooClass();
Foo *foo = buildFoo(10.0,5.0);
std::cout << foobar(foo,5.0) << std::endl;
Py_Finalize();
}
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 在静态库中嵌入类方法
- 如何制作一个将函数作为参数的类方法
- 从父类方法返回子类对象
- 使用用户定义的参数调用future/async并调用类方法
- 重载类方法的不明确调用
- 单独定义模板化嵌套类方法的正确语法
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 如何访问由共享指针保存的类方法?
- 将子类方法声明为基类的友元
- 我的模板类方法返回错误类型?
- Qt将信号与另一个类方法连接
- 我无法使用C++指针指向类方法返回的 std::vector
- 如何在成为指向基类的指针后保留对子类方法的使用?
- 检查类方法中是否(此 == nullptr)
- 从基类实例调用派生类方法而不进行强制转换
- 函数从唯一代码调用正确的子类方法
- C++ - 如何在不静态的情况下将回调绑定到类方法?
- 带有类方法的 Cython 回调
- 在C++中嵌入Cython类方法