我正在使用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必须是vector类型。如何将向量传递给foo以便foo可以编辑数据?
谢谢!
答案 0 :(得分:2)
我不确定我是否理解你的问题。我相信你想把一个数组从MATLAB传递给你的mex函数,然后mex函数调用一个对这个数据数组进行操作的C ++函数,并调用vector
。然后vector
包含C ++函数所做的任何结果,并且您希望将此数据传递回MATLAB。
首先,我们来处理从MATLAB获取数据到您的MEX函数
int const *data_in = static_cast<int const *>(mxGetData(prhs[0]));
现在,data_in
指向您传入的数据。顺便说一下,您确定数组包含int
吗?默认情况下,MATLAB将double
用于所有内容。
您的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
以接受std::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
请记住,MATLAB以列主格式存储矩阵,不像C&amp; C ++。根据{{1}}函数的工作方式,您可能必须转置返回的向量,在这种情况下,您不能使用foo
进行复制,您必须编写嵌套循环。
答案 1 :(得分: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
),那么您要求的是数组第一个元素的值(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 );