假设我有一个.h文件,其中包含以下代码:
class MyClass
{
public:
int Attribute1;
int Attribute2;
MyClass(){};
virtual ~MyClass(){};
virtual void Method1(string var1);
virtual float Method2(float var2);
};
和一个相关的.pyx文件:
cdef class PyClass:
cdef MyClass *classptr
[standard __cinit__ and __dealloc__ declarations ]
cdef int Attribute1;
def Method1(self, var1):
self.classptr.Method1(var1)
和pxd文件,带有:
cdef extern from "mycode.h":
cdef cppclass MyClass:
MyClass() except +
int Attribute1
void Method1(string)
我使用setup.py创建了一个.so库,以便在python模块中导入。
请注意,尽管c++中存在MyClass::Method2和MyClass::Attribute2,但我在Cython中没有提到它们,因此它们在.so库中不可见。也许我这样做是因为它们被MyClass::Method1((间接使用,或者只是因为我不打算在python代码中调用它们。
这是一种可能导致问题/怪异行为的不良做法吗?如果是,为什么?
cdef class PyClass:
cdef MyClass *classptr
# ...
cdef int Attribute1;
Attribute1
不会按照你的想法行事。它是作为PyClass
的一部分存储的单独值,与classptr
中的Attribute1
无关。你可能想写一个属性。
然而,要回答您的问题:
是的,你可以只包装你感兴趣的特定函数。Cython不需要知道C++类的所有细节,它只需要知道足够的细节,就可以使用它们生成有效的C++代码。省略一些有用的快速例子:
模板。例如,
std::string
实际上是一个模板typedef,但Cython包装器可能不一定知道这一点,或者可选的分配器模板类型,或者Cython并不真正支持的数字模板类型。复杂的继承层次结构:您关心的函数是否真的来自基类并不重要。只需包装您正在使用的派生类。
返回其他类的接口-因为这样你就需要包装第二个类(这可能会暴露第三个类…(
除了不能调用尚未从python中封装的代码之外,真的没有任何后果。Cython的C++支持有些不完整(而且可能永远都是(,通常需要给它一个简化的C++接口来完成任何事情。