将多维 C 数组复制到 Matlab mxArray 类型
copy multi-dimension C array to Matlab mxArray type
我正在编写打开 Matlab API 引擎的 C++ 代码。在演示文件 Matlab_ROOT/extern/examples/eng_mat/engdemo.cpp 中,它展示了如何将简单的一维 c 样式数组复制到 mxArray:
mxArray *T = NULL; double time[10] = {};
T = mxCreateDoubleMatrix( 1,10,mxREAL);
memcpy((void*)mxGetPr(T), (void*)time, sizeof(time));
我能看懂这段代码;所以 1d mxArray
对象线性存储元素。
但是,假设我有一个 2d(或更多)c 数组和 mxArray
相同大小:
double time[3][5];
mxArray *T;
T = mxCreateDoubleMatrix(3,5,mxREAL);
并且我想将c数组时间的元素复制到mxArray
T
中。我怎样才能做到这一点?我想如果我使用 memcpy
,它将取决于 mxArray
对象中元素存储的顺序。谢谢!
无论您的 mxArray
的维数如何,matlab 始终将其作为连续块存储在内存中(列一阶)。也就是说,如果您的矩阵 M
是 2×3
M = [ 11, 12, 13;
21, 22, 23 ];
在内存中,Matlab将其存储为
[11, 21, 12, 22, 13, 23]
(与 M(:)
相同的顺序)。
因此,要将 double[3][5]
转换为 mxArray
,您必须执行 多个 memcpy
命令:
double* ptr = mxGetPr( T );
for ( int i=0; i<3; i++ )
memcpy( (void*)(ptr+i*5), (void*)time[i], 5*sizeof(double) );
另一个 Matlab 演示文件 matlabroot/extern/examples/refbook/arrayFillSetData.c 中说明了执行此操作的一种方法。除了 c 样式数组必须是 Matlab 支持的类型和线性形式外,一切都很好。 Matlab 将 2d 数组存储在主要列中,将 c 存储在主要行中,因此必须小心。可能需要转置操作。
#define ROWS 2
#define COLUMNS 2
#define ELEMENTS 4
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
UINT16_T *dynamicData; /* pointer to dynamic data */
const UINT16_T data[] = {2, 3, 2, 1}; /* existing data */
mwSize index;
/* Check for proper number of arguments. */
if ( nrhs != 0 ) {
mexErrMsgIdAndTxt("MATLAB:arrayFillSetData:rhs",
"This function takes no input arguments.");
}
/* Create a local array and load data */
dynamicData = mxCalloc(ELEMENTS, sizeof(UINT16_T));
for ( index = 0; index < ELEMENTS; index++ ) {
dynamicData[index] = data[index];
}
/* Create a 0-by-0 mxArray; you will allocate the memory dynamically */
plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT16_CLASS, mxREAL);
/* Point mxArray to dynamicData */
mxSetData(plhs[0], dynamicData);
mxSetM(plhs[0], ROWS);
mxSetN(plhs[0], COLUMNS);
/* Do not call mxFree(dynamicData) because plhs[0] points to dynamicData */
return;
}
我正在编写打开 Matlab API 引擎的 C++ 代码。在演示文件 Matlab_ROOT/extern/examples/eng_mat/engdemo.cpp 中,它展示了如何将简单的一维 c 样式数组复制到 mxArray:
mxArray *T = NULL; double time[10] = {};
T = mxCreateDoubleMatrix( 1,10,mxREAL);
memcpy((void*)mxGetPr(T), (void*)time, sizeof(time));
我能看懂这段代码;所以 1d mxArray
对象线性存储元素。
但是,假设我有一个 2d(或更多)c 数组和 mxArray
相同大小:
double time[3][5];
mxArray *T;
T = mxCreateDoubleMatrix(3,5,mxREAL);
并且我想将c数组时间的元素复制到mxArray
T
中。我怎样才能做到这一点?我想如果我使用 memcpy
,它将取决于 mxArray
对象中元素存储的顺序。谢谢!
无论您的 mxArray
的维数如何,matlab 始终将其作为连续块存储在内存中(列一阶)。也就是说,如果您的矩阵 M
是 2×3
M = [ 11, 12, 13;
21, 22, 23 ];
在内存中,Matlab将其存储为
[11, 21, 12, 22, 13, 23]
(与 M(:)
相同的顺序)。
因此,要将 double[3][5]
转换为 mxArray
,您必须执行 多个 memcpy
命令:
double* ptr = mxGetPr( T );
for ( int i=0; i<3; i++ )
memcpy( (void*)(ptr+i*5), (void*)time[i], 5*sizeof(double) );
另一个 Matlab 演示文件 matlabroot/extern/examples/refbook/arrayFillSetData.c 中说明了执行此操作的一种方法。除了 c 样式数组必须是 Matlab 支持的类型和线性形式外,一切都很好。 Matlab 将 2d 数组存储在主要列中,将 c 存储在主要行中,因此必须小心。可能需要转置操作。
#define ROWS 2
#define COLUMNS 2
#define ELEMENTS 4
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
UINT16_T *dynamicData; /* pointer to dynamic data */
const UINT16_T data[] = {2, 3, 2, 1}; /* existing data */
mwSize index;
/* Check for proper number of arguments. */
if ( nrhs != 0 ) {
mexErrMsgIdAndTxt("MATLAB:arrayFillSetData:rhs",
"This function takes no input arguments.");
}
/* Create a local array and load data */
dynamicData = mxCalloc(ELEMENTS, sizeof(UINT16_T));
for ( index = 0; index < ELEMENTS; index++ ) {
dynamicData[index] = data[index];
}
/* Create a 0-by-0 mxArray; you will allocate the memory dynamically */
plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT16_CLASS, mxREAL);
/* Point mxArray to dynamicData */
mxSetData(plhs[0], dynamicData);
mxSetM(plhs[0], ROWS);
mxSetN(plhs[0], COLUMNS);
/* Do not call mxFree(dynamicData) because plhs[0] points to dynamicData */
return;
}