我希望我的问题不重复,我尽力在网上找到答案,但不成功。
我正在构建Matlab和我自己的用C ++编码的库之间的绑定,所以我有一个用于每个C ++类的Matlab包装类和一个包装类可以调用C ++方法和属性的mex。
在mex文件中将对象创建为持久对象,然后将其作为mxUINT64_CLASS
传递给Matlab包装器,其中包含以下内容:
mxArray* handle = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
*reinterpret_cast<myClass**>(mxGetPr(handle)) = (myClass*)obj;
当调用一个方法时,包装类将句柄传递给mex文件,其中原始C ++指针的计算方法如下:
template<class T>
T* handleToPtr(const mxArray* handle){
if (mxGetClassID(handle) != mxUINT64_CLASS
|| mxIsComplex(handle) || mxGetM(handle)!=1 || mxGetN(handle)!=1)
mexErrMsgTxt("Parameter is not an ObjectHandle type.");
// We *assume* we can store thermoState pointer in the mxUINT64 of handle
T* obj = *reinterpret_cast<T**>(mxGetPr(handle));
if (!obj) // gross check to see we don't have an invalid pointer
mexErrMsgTxt("Parameter is NULL. It does not represent an ObjectHandle object.");
return obj;
}
其中T是我正在处理的对象的类。
这个策略适用于很多课程,但现在我遇到了一些非常奇怪的问题。 对于一个特定的类,我无法解除引用类属性的指针(访问其方法时没有任何问题)。 这里有一个例子:
myClass* obj = handleToPtr<myClass>(prhs[1]);
std::cout << "obj = " << obj << std::endl;
std::cout << "&obj->Name_ = " << &obj->Name_ << std::endl;
plhs[0] = mxCreateString(obj->Name_.c_str());
这不会让我得到Name_的正确值,而只是垃圾。奇怪的是,我可以使用gdb获得正确的值。这确实是我在gdb中的输出:
obj = 0x7fffd4f09740
&obj->Name_ = 0x7fffd4f09798
[Switching to Thread 0x7fffe2cae700 (LWP 9695)]
Breakpoint 1, mexFunction (nlhs=1, plhs=0x7fffc88d8980, nrhs=2, prhs=0x7fffc88d8e10) at propModuleMex.cpp:157
157 plhs[0] = mxCreateString(obj->Name_.c_str());
(gdb) print obj
$1 = (propModule *) 0x7fffd4f09740
(gdb) print &obj->Name_
$2 = (std::string *) 0x7fffd4f09778
(gdb) print obj->Name_
$3 = {static npos = <optimised out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
_M_p = 0x7fffd4c980f8 "Object Name"}}
正如您所看到的,对象obj
的指针在gdb和实际计算中是相同的(即由std::cout
打印),但是指向属性的指针在最后两个时是不同的对xxx98
的数字xxx78
和gdb似乎是正确的,因为它可以正确地取消引用它。
这种奇怪的现象不会发生在许多其他类中,而且对于具有我的C ++库的另一个版本的此类也不会发生这种现象。 什么有效和无效的主要区别在于我在这里使用的类不是基类,而是从其他类继承。在所有其他情况下,我总是使用指向基类的指针(在Matlab转换之前和之后转换为感兴趣的子类)。我真诚地认为这不是问题所在。
我希望这里的任何人能够指出我正确的方向,如果我发现更多,我会告诉你的。
的Alessandro
修改
我曾尝试将reinterpret_cast
与基类一起使用,但这并没有解决问题。
我也尝试使用void*
指针:相同的结果。
我还在我的库中为属性Name_
添加了一个get方法,但是我的垃圾最糟糕。所以似乎属性Name_
(以及其他一些,但不是全部)在任何情况下都有这个问题。