Matlab mex文件中指向对象属性的C ++指针的小不匹配

时间:2015-04-23 13:15:27

标签: c++ matlab pointers mex

我希望我的问题不重复,我尽力在网上找到答案,但不成功。

我正在构建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_(以及其他一些,但不是全部)在任何情况下都有这个问题。

0 个答案:

没有答案