1

我正在使用 MEX 将我的 C++ 代码与 MATLAB 接口。我的 C++ 代码要求输出类型为 vector 。由于我是 C++ 新手,我对指针的工作方式非常困惑。我将从 MATLAB 获取一个输入数组

int *data_array_ptr
data_array_ptr=(int *)mxGetData(prhs[0]);
a = mxGetM(prhs[0]);
int int_data[a];
copy(*data_array_ptr, *data_array_ptr+ a, int_data);

现在,int_data 应该包含存储在 data_array_ptr 位置的所有数据......它这样做了吗?

然后,

double *data_out_ptr;

plhs[0]= mxCreateDoubleMatrix( (mwSize)m, (mwSize)n, mxREAL); 
data_out_ptr= mxGetPr(plhs[0]);
len6=mxGetM(plhs[0]);
vector<double> data_out_data(*data_out_ptr,*data_out_ptr+len6);

这应该将空输出矩阵的内容放入名为 data_out_data 的向量中。它这样做吗?

然后,我想将 data_out_data 和 int_data 都传递给 c++ 函数。但是,我想将 data_out_data 作为指针传递,以便 c++ 函数将用数据填充向量,然后当函数完成时,MEX 函数将看到现在填充的向量并能够将其转换回双精度数组可以填充plhs[0]。

所以,像

mexFunction(plhs[],prhs[]){

int *data_array_ptr
data_array_ptr=(int *)mxGetData(prhs[0]);
a = mxGetM(prhs[0]);
int int_data[a];
copy(*data_array_ptr, *data_array_ptr+ a, int_data);

 double *data_out_ptr;
plhs[0]= mxCreateDoubleMatrix( (mwSize)m, (mwSize)n, mxREAL); 
data_out_ptr= mxGetPr(plhs[0]);
len6=mxGetM(plhs[0]);
vector<double> data_out_data(*data_out_ptr,*data_out_ptr+len6);



foo(int_data, *data_out_data)

copy(data_out_data.begin(), data_out_data.end(), data_out_ptr);
}

并且在 foo 返回时, data_out_data 将被填充。我的函数没有返回参数 data_out_data 必须是向量类型。如何将向量传递给 foo 以便 foo 可以编辑数据?

谢谢!!

4

2 回答 2

2

我不确定我是否正确理解了您的问题。我相信您想将一个数组从 MATLAB 传递给您的 mex 函数,然后 mex 函数调用一个对该数据数组进行操作的 C++ 函数,以及一个vector. then 包含 C++ 函数执行的任何操作的vector结果,并且您希望将此数据传递回 MATLAB。


首先,让我们处理从 MATLAB 获取数据到您的 MEX 函数

int const *data_in = static_cast<int const *>(mxGetData(prhs[0]));

现在,data_in指向您传入的数据。顺便问一下,您确定数组包含ints 吗?默认情况下,MATLABdouble用于所有内容。

你的 C++ 函数会修改这个数组吗?如果没有,您可以只使用指针和元素数调用它,而不是执行复制。

例如,如果 的签名foo

foo( int const *data_in, mwSize num_data_in, std::vector<double> *data_out );

你可以称之为

foo( data_in, mxGetNumberOfElements(prhs[0]), &data_out );

如果您确实需要修改数据,并且/或者不能修改foo,只需创建一个向量来保存数据的副本。

std::vector<int> data_in_vec( data_in, data_in + mxGetNumberOfElements(prhs[0]) );
foo( data_in_vec.data(), data_out );

至于foo函数,在调用它之前是否需要正确调整向量的大小?如果是这样,

std::vector<double> data_out( m * n );  // creates a vector with m * n elements
foo( data_in_vec.data(), &data_out );

如果可能,修改foo以接受 astd::vector<double>&而不是std::vector<double> *. 然后你可以称它为

foo( data_in_vec.data(), data_out );

此外,如果可以选择,我会foo根据需要调整向量的大小,而不是要求调用者这样做。


现在,将数据返回到 MATLAB。

plhs[0] = mxCreateDoubleMatrix( m, n, mxReal );
std::copy( data_out.data(), data_out.data() + data_out.size(), mxGetPr(plhs[0]) );

上述行假设向量的大小不大于m * n

请记住,与 C 和 C++ 不同,MATLAB 以列优先格式存储矩阵。根据foo函数的工作方式,您可能必须转置返回的向量,在这种情况下,您不能用于std::copy复制,您必须编写嵌套循环。

于 2012-08-08T23:20:51.347 回答
1

您对指针的取消引用超出了应有的范围...

int *data_array_ptr;
// ...
copy(*data_array_ptr, *data_array_ptr+ a, int_data);

当您被要求提供指向 的开始和结束指针时copy,您需要执行以下操作:

copy(data_array_ptr, data_array_ptr+ a, int_data);

现在您已经提供了两个内存地址。第一个,data_array_ptr,是数组的起始地址。第二个data_array_ptr+a是数组末尾之后的元素地址。

如果您取消引用指针 ( *data_array_ptr),那么您要求的是数组第一个元素的(an int)。同样,*data_array_ptr+a将首先获取第一个数组元素的值,然后添加a到它。这不是你想要的。

因此,按照建议更改所有调用copy以及vector构造函数。

至于你关于你的foo函数的问题,如果你需要传递一个向量,那么像这样声明它:

void foo( int * int_data, std::vector<double> & data_out_data )

假设您在上面提供了这些变量的定义。我认为您是这样称呼的:

// ...

int int_data[a];
copy(*data_array_ptr, *data_array_ptr+ a, int_data);

// ...

vector<double> data_out_data(data_out_ptr, data_out_ptr+len6);

// ...

foo( int_data, data_out_data );

请注意,如果您不知道int_data内部数组的长度foo(基于 的长度data_out_data),您还应该在参数列表中要求一个大小foo

foo( int_data, a, data_out_data );
于 2012-08-08T23:15:11.670 回答