将向量传递给函数并返回向量并重铸

时间:2012-08-08 22:52:56

标签: c++ matlab pointers vector mex

我正在使用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可以编辑数据?

谢谢!

2 个答案:

答案 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_datafoo数组的长度(基于data_out_data的长度),您还应该在参数列表中需要一个大小foo

foo( int_data, a, data_out_data );