代码之家  ›  专栏  ›  技术社区  ›  yu quan

将多维C数组复制到Matlab mxArray类型

  •  2
  • yu quan  · 技术社区  · 9 年前

    我正在编写一个c++代码来打开Matlab API引擎。在演示文件Matlab_ROOT/extern/examples/eng_mat/engdemo中。cpp,它展示了如何将简单的1dc样式数组复制到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(mx阵列) 尺寸相同:

    double time[3][5]; 
    mxArray *T; 
    T = mxCreateDoubleMatrix(3,5,mxREAL);
    

    我想将c数组时间的元素复制到 mxArray(mx阵列) T 。我该怎么做?我想如果我使用 memcpy ,这取决于元素存储的顺序 mxArray(mx阵列) 物体。谢谢

    2 回复  |  直到 9 年前
        1
  •  3
  •   Shai    9 年前

    无论你的 mxArray matlab总是将其作为一个连续块存储在内存中(列的第一顺序)。也就是说,如果你的矩阵 M 是2乘3

    M = [ 11, 12, 13;
          21, 22, 23 ];
    

    在内存中,Matlab将其存储为

    [11, 21, 12, 22, 13, 23]
    

    (如果你这样做,你会得到同样的订单 M(:) ).

    因此,要转换 double[3][5] mxArray(mx阵列) 你必须发行 几个 memcpy 命令:

    double* ptr = mxGetPr( T );
    for ( int i=0; i<3; i++ )
        memcpy( (void*)(ptr+i*5), (void*)time[i], 5*sizeof(double) );
    
        2
  •  2
  •   yu quan    9 年前

    另一个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;
    }