有人可以解释为什么这个扩展会崩溃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(KeyPoints的向量),因为没有必要重现崩溃。
我构建了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 ++(我将它构建为一个lib,然后我链接到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 bug吗?一个opencv bug?还是一个C ++错误?或者我做错了什么? 我的编译器是visual studio express 2009
答案 0 :(得分:0)
我找到了问题的原因。没有错误。这是我的问题。我正在混合运行时库:-( 一个月前,我开始将一些数字python代码翻译成C ++,使用cython作为连接来验证一致的结果。当我构建cython扩展时,我用它来获取此链接器警告:
LINK:警告LNK4098:defaultlib'MSVCRTD'与使用其他lib冲突;使用/ NODEFAULTLIB:库
但我不知道如何删除它,代码似乎工作。我实际上在这种情况下翻译了相当多的代码,直到现在我才遇到问题。在中间加几个休息时间,我完全忘了这个。
我必须将/ MDd添加到extra_compile_args以匹配我的C ++库。然后我会遇到我需要python27_d.exe的问题。一旦我尝试构建它,但我还必须构建我使用的每个库的调试版本!不可行!
我在How to debug C extensions for Python on Windows找到了一个技巧 我不得不在C:\ Python27 \ include \ pyconfig.h中注释#define Py_DEBUG然后将python27.exe复制到python27_d.exe 现在我可以用/ MDd构建
之后我停止了崩溃。