【问题标题】:How to access a matrix in a matlab struct's field from a mex function?如何从 mex 函数访问 matlab 结构字段中的矩阵?
【发布时间】:2011-02-18 07:19:03
【问题描述】:

我试图弄清楚如何从 mex 函数访问存储在 matlab 结构中的字段中的矩阵。

这太啰嗦了……让我解释一下:

我有一个 matlab 结构,其定义如下:

matrixStruct = struct('matrix', {4, 4, 4; 5, 5, 5; 6, 6 ,6})

我有一个 mex 函数,我希望能够在其中接收指向矩阵中第一个元素的指针(矩阵 [0] [0],用 c 术语表示),但我一直无法弄清楚如何做到这一点。

我尝试了以下方法:

/* Pointer to the first element in the matrix (supposedly)... */
double *ptr = mxGetPr(mxGetField(prhs[0], 0, "matrix");  

/* Incrementing the pointer to access all values in the matrix */
for(i = 0; i < 3; i++){  
    printf("%f\n", *(ptr + (i * 3)));
    printf("%f\n", *(ptr + 1 + (i * 3)));
    printf("%f\n", *(ptr + 2 + (i * 3)));
}

最终打印出来的内容如下:

4.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000

我还尝试了以下变体,认为嵌套函数调用可能有些不妥,但无济于事:

/* Pointer to the first location of the mxArray */
mxArray *fieldValuePtr = mxGetField(prhs[0], 0, "matrix");

/* Get the double pointer to the first location in the matrix */
double *ptr = mxGetPr(fieldValuePtr);

/* Same for loop code here as written above */

有没有人知道我如何才能实现我的目标,或者我可能做错了什么?

谢谢!

编辑:根据 yuk 的评论,我尝试对一个结构体执行类似的操作,该结构体具有一个名为 array 的字段,该字段是双精度的一维数组。

包含数组的结构体定义如下:

arrayStruct = struct('array', {4.44, 5.55, 6.66})

我在 mex 函数中对 arrayStruct 尝试了以下操作:

mptr = mxGetPr(mxGetField(prhs[0], 0, "array"));

printf("%f\n", *(mptr));
printf("%f\n", *(mptr + 1));
printf("%f\n", *(mptr + 2));

...但输出遵循之前打印的内容:

4.440000
0.000000
0.000000

【问题讨论】:

  • 我对 mex 文件没有太多经验,只是一些想法。您正在尝试访问 MATLAB 中的元胞数组变量。您确定数据会因此存储吗?如果将双数组放入结构中会发生什么? matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6])
  • yuk - 如果我在我的问题上附加的内容是您建议的内容,请告诉我。
  • 不,您仍然定义了元胞数组。我想让你试试这个:arrayStruct = struct('array', [4.44, 5.55, 6.66])。注意方括号 [],而不是 {}。
  • 您是否愿意将其发布为答案,因为您解决了我的问题!非常感谢!

标签: matlab struct mex


【解决方案1】:

您正在尝试访问 MATLAB 中的元胞数组变量。您确定数据会因此存储吗?如果将双数组放入结构中会发生什么?

matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6])

我认为问题在于 MATLAB 如何将数据存储在元胞数组中。尝试运行:

double1 = 1;
double2 = 1:2;
cellempty = {[]};
celldouble1 = {1};
celldouble2 = {1:2};
cell2doubles = {1,2};
whos

输出:

Name              Size            Bytes  Class     Attributes
  cell2doubles      1x2               136  cell                
  celldouble1       1x1                68  cell                
  celldouble2       1x1                76  cell                
  cellempty         1x1                60  cell                
  double1           1x1                 8  double              
  double2           1x2                16  double              

您可以看到元胞数组的每个元素占用了数字大小的额外 60 个字节。

【讨论】:

    【解决方案2】:

    struct('field', {a b c}) 是 struct 构造函数的一种特殊形式,它创建一个与元胞数组大小相同的结构 array,将元胞的每个元素放入相应的字段“字段”中结构的元素。也就是这个:

    s = struct('field', {a b c});
    

    产生与此相同的结果:

    s(1).field = a;
    s(2).field = b;
    s(3).field = c;
    

    解决您的问题的方法是使用方括号形成一个常规(非单元)数组,如下所示:

    matrixStruct = struct('matrix', [4, 4, 4; 5, 5, 5; 6, 6 ,6]);
    

    【讨论】:

    • 或者,如果你真的想在单个结构项中使用元胞数组:使用struct('matrix', {{4, 4, 4; 5, 5, 5; 6, 6, 6}})
    【解决方案3】:

    我经历过这个:我有一个结构体,它的字段是一个矩阵。例如,在 C++ 中,相应的结构是 double**。尝试使用 engGetVariable(engine,MyStruct.theField) 访问该字段失败。我使用一个临时变量来存储MyStruct.theField,然后使用engGetVariable(engine, tempVar),代码从结构中获取矩阵字段看起来像这样

    // Fetch struct field using a temp variable
    std::string tempName = std::string(field_name) + "_temp";
    std::string fetchField = tempName + " = " + std::string(struct_name) 
            + "." + std::string(field_name) + "; ";
    matlabExecute(ep, fetchField);
    mxArray *matlabArray = engGetVariable(ep, tempName.c_str());
    
    // Get variable elements
    const int count = mxGetNumberOfElements(matlabArray);
    T *data = (T*) mxGetData(matlabArray);
    for (int i = 0; i < count; i++)
        vector[i] = _isnan(data[i]) ? (T) (int) -9999 : (T) data[i];
    
    // Clear temp variable
    std::string clearTempVar = "clear " + tempName + "; ";
    matlabExecute(ep, clearTempVar);
    
    // Destroy mx object
    mxDestroyArray(matlabArray);
    

    非常类似将矩阵字段设置为结构我做到了

    // Create temp variable
    mxArray* array = convertVectorToMxArray(mat, nb_rows, nb_cols);  
    const std::string temp_name = array_name + "_temp";
    int ret = engPutVariable(ep, temp_name.c_str(), array);
    
    // Set variable to struct field
    const std::string cmd = std::string(array_name + " = " + temp_name + "; ");
    matlabExecute(ep, cmd);
    
    // Delete array
    mxDestroyArray(array);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      相关资源
      最近更新 更多