MCo*_*Cor 5 c++ python wrapper cython
我正在开发一个Python项目,我希望与已编写的C++包接口.由于我将在本项目的其他部分使用Cython,我更喜欢使用Cython进行换行.
简而言之,我需要包装一个返回自定义类型Bar对象的函数FooBar.
这是Bar.h:
#include <cstddef> // For size_t
#include <vector>
/* data returned by function FooBar()*/
class Bar {
public:
size_t X;
std::vector<size_t> Y;
std::vector<double> Z;
std::vector<double> M;
std::vector<size_t> N;
};
Bar FooBar(const std::vector<double> & O, size_t P, size_t Q);
Run Code Online (Sandbox Code Playgroud)
和PyBar.pyx:
from libcpp.vector cimport vector
cdef extern from "Bar.h":
cdef cppclass Bar:
size_t X
vector[size_t] Y
vector[double] Z
vector[double] M
vector[size_t] N
cdef Bar FooBar(const vector[double] & O, size_t P, size_t Q)
cdef class PyBar:
cdef Bar *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, O, P, Q):
C_Bar = FooBar(O, P, Q)
self.thisptr = &C_Bar
def __dealloc__(self):
del self.thisptr
Run Code Online (Sandbox Code Playgroud)
实际问题:这是否是我想要做的正确方法?作为参考,如果我只是试图自己包装类我没有问题:我可以导入模块,使用PyBar()创建对象,并且在类上实现的底层C方法可以工作.问题是尝试包装一个返回C++类对象的函数.在野外,我实际上永远不会想要创建任何不是由FooBar创建的Bar对象的PyBar表示,所以这是我经过多次努力之后决定的方法.
关于问题的第一部分,我认为更优雅的更改是将 FooBar 定义为:
Bar* FooBar(const std::vector<double> & O, size_t P, size_t Q);
Run Code Online (Sandbox Code Playgroud)
并让它返回一个“新”分配的指针。我认为在您最初的 Cython 代码中,__cinit__您将创建一个堆栈分配的 Bar,获取其指针,然后该指针将过期,导致最终的灾难。
另一种可能有效的解决方案是让 FooBar 返回 Bar,更改 PyBar 以便它启动
cdef class PyBar:
cdef Bar this_obj
def __cinit__(self, O, P, Q):
self.this_obj = FooBar(O,P,Q)
Run Code Online (Sandbox Code Playgroud)
即保留一个对象而不是指针。没有__dealloc__必要。
我不知道未定义的符号错误......
| 归档时间: |
|
| 查看次数: |
1571 次 |
| 最近记录: |