结构变量数组中的mexfunction变量的错误

时间:2014-12-19 05:30:00

标签: c matlab mex

最近,我尝试使用结构变量编写mexfunctions。 我观看了教程但由于变量值的传递方式而感到困惑。 以下示例(mexfunction_using_ex_wrong.m & mexfunction_using_ex_wrong.cpp)演示了如何在mexfunction中获取从matlab传递的变量。 但是,在这种情况下,结果是:

address i_c1=2067094464 i_c2=2067094464
        i_c1=10         i_c2=10
address i_c1=1327990656 i_c2=2067100736
        i_c1=2          i_c2=20
address i_c1=2067101056 i_c2=2067063424
        i_c1=3          i_c2=30

可以看出,c1&的第一个元素。 c2结构变量的数组意外相同。

但是,在另一个例子(mexfunction_using_ex_correct.m & mexfunction_using_ex_correct.cpp)中,结构变量的数组1(b1)和数组2(b2)的元素与我期望的不相关。 结果是:

address i_b1=1978456576 i_b2=1326968576
        i_b1=1          i_b2=10
address i_b1=1978456584 i_b2=1326968584
        i_b1=2          i_b2=20
address i_b1=1978456592 i_b2=1326968592
        i_b1=3          i_b2=30

然而,在编程中使用第一个例子更为常见。所以有人可以解释为什么在第一个例子中i_c1&的地址i_c2是一样的吗?

以下代码为mexfunction_using_ex_wrong.m

clc
clear all
close all

mex mexfunction_using_ex_c_wrong.cpp;

a.b(1).c1=double(1);
a.b(2).c1=double(2);
a.b(3).c1=double(3);

a.b(1).c2=double(1);
a.b(2).c2=double(2);
a.b(3).c2=double(3);

mexfunction_using_ex_c_wrong(a);

以下代码为mexfunction_using_ex_c_wrong.cpp

#include "mex.h"

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) 
{   
     int i, j, k;

     double *i_c1;
     double *i_c2;

     // for struct variables(pointers) inside fcwcontext
     mxArray *mx_b, *mx_c1, *mx_c2;    

     mx_b=mxGetField(prhs[0], 0, "b");

    for(i = 0;i < 3;i=i+1)
    {               
        mx_c1=mxGetField(mx_b, i, "c1");
        mx_c2=mxGetField(mx_b, i, "c2");

        i_c1=mxGetPr(mx_c1);
        i_c2=mxGetPr(mx_c2);        

        *i_c2=(*i_c2)*10;

        printf("address i_c1=%d i_c2=%d\n", i_c1, i_c2);
        printf(" i_c1=%g i_c2=%g\n", *i_c1, *i_c2);               
    }                  
}

以下代码为mexfunction_using_ex_c_correct.m

clc
clear all
close all

mex mexfunction_using_ex_correct.cpp;

a.b1(1)=double(1);
a.b1(2)=double(2);
a.b1(3)=double(3);

a.b2(1)=double(1);
a.b2(2)=double(2);
a.b2(3)=double(3);

mexfunction_using_ex_correct(a);

以下代码为mexfunction_using_ex_c_correct.cpp

#include "mex.h"

void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) 
{   
     int i, j, k;

     double *i_b1;
     double *i_b2;

     mxArray *mx_b1, *mx_b2;    

     mx_b1=mxGetField(prhs[0], 0, "b1");
     mx_b2=mxGetField(prhs[0], 0, "b2");

    for(i = 0;i < 3;i=i+1)
    {                       
        i_b1=mxGetPr(mx_b1);
        i_b2=mxGetPr(mx_b2);        

        i_b2[i]=i_b2[i]*10;

        printf("address i_b1=%d i_b2=%d\n", &i_b1[i], &i_b2[i]);
        printf(" i_b1=%g i_b2=%g\n", i_b1[i], i_b2[i]);                
    }                  
}

1 个答案:

答案 0 :(得分:1)

地址不是&#34;意外相同&#34; - 由于MATLAB的内部写时复制优化,他们有意 。如果您查看MEX文档,您会看到分散在...周围的警告。

  

Do not modify any prhs values in your MEX-file. Changing the data in these read-only mxArrays can produce undesired side effects.

......以各种形式......

  

Note Inputs to a MEX-file are constant read-only mxArrays. Do not modify the inputs. Using mxSetCell* or mxSetField* functions to modify the cells or fields of a MATLAB® argument causes unpredictable results.

...试图明确表示你应该绝对不会修改你收到的任何输入。通过对输入数据调用mxGetPr()并像对i_b2i_c2一样写回指针,您就可以直接进入&#34;不可预测的结果&#34;领土 - 如果你在电话会议结束后在MATLAB工作区查看a.b(1).c1,即使你只是&#34;只有&#34;已更改c2

从MEX,您在不了解或访问MATLAB内部管理的情况下查看原始数据存储,因此唯一的安全修改方式是使用mxCreate*mxDuplicate*函数来获取您自己的安全数​​组,然后您可以随意执行任何操作,并通过plhs传回MATLAB。

那就是说,我承认在一个实例中滥用in-place modification可以获得显着的性能提升,我可以保证我的数据是独特的和非共享的,但它最多是不受支持的,最坏的是危险的