谁能解释为什么这个扩展会导致 python 崩溃?
我已经为此发疯了好几个小时,我无法解释。
我已经简化了我的代码,以便它只显示重现崩溃所需的行:
我在“test_class.h”中有一个非常简单的 C++ 类,它使用了几个 opencv 类型 cv::Mat 和 cv::KeyPoint:
class TestClass
{
public:
TestClass();
cv::Mat& get_current_frame_descriptors();
std::vector<cv::KeyPoint> _current_frame_points;
cv::Mat _current_frame_descriptors;
};
“test_class.cpp”
TestClass::TestClass()
{
}
Mat& TestClass::get_current_frame_descriptors()
{
return _current_frame_descriptors;
}
然后我在“test_class.pyx”中有一个 cython 包装器:
from libcpp.vector cimport vector
cdef extern from "opencv2/core/core.hpp" namespace "cv":
cdef cppclass Mat:
Mat()
int dims, rows, cols, flags
cdef extern from "test_class.h":
cdef cppclass TClass "TestClass":
TClass()
Mat _current_frame_descriptors
Mat& get_current_frame_descriptors()
cdef class TestClass:
cdef TClass *TClass_ptr
def __cinit__(self):
self.TClass_ptr = new TClass()
def get_descriptors1(self):
m = self.TClass_ptr.get_current_frame_descriptors()
print m.dims
print m.rows
print m.cols
print m.flags
def get_descriptors2(self):
m = self.TClass_ptr._current_frame_descriptors
print m.dims
print m.rows
print m.cols
print m.flags
请注意,TClass 没有声明 _current_frame_points(关键点的向量),因为没有必要重现崩溃。
我构建了 cython 扩展并对其进行了测试:
>>>import test_class
>>>m = test_class.TestClass()
opencv Mat _current_frame_descriptors 为空,因此 dims、rows 和 cols 为零:
>>>m.get_descriptors1()
0
0
0
1124007936
>>>m.get_descriptors2()
这会导致python崩溃!!!
现在,如果我在 test_class.h 中反转 _current_frame_descriptors 和 _current_frame_points 的其他声明,那么我不会崩溃!!!!
class TestClass
{
public:
TestClass();
cv::Mat& get_current_frame_descriptors();
cv::Mat _current_frame_descriptors;
std::vector<cv::KeyPoint> _current_frame_points;
};
现在我重建 C++(我将它构建为一个库,然后我用 cython 扩展链接到)我重建 cython 扩展并测试它
>>>import test_class
>>>m = test_class.TestClass()
opencv Mat _current_frame_descriptors 是空的,所以当我这样做时
>>>m.get_descriptors1()
0
0
0
1124007936
>>>m.get_descriptors2()
0
0
0
1124007936
现在我得到了正确的结果!!!
这怎么可能?这是一个 cython 错误吗?一个opencv错误?还是 C++ 错误?还是我做错了什么?我的编译器是 Visual Studio Express 2009