最近,我尝试使用结构变量编写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]);
}
}
答案 0 :(得分:1)
地址不是&#34;意外相同&#34; - 由于MATLAB的内部写时复制优化,他们有意 。如果您查看MEX文档,您会看到分散在...周围的警告。
......以各种形式......
...试图明确表示你应该绝对不会修改你收到的任何输入。通过对输入数据调用mxGetPr()
并像对i_b2
和i_c2
一样写回指针,您就可以直接进入&#34;不可预测的结果&#34;领土 - 如果你在电话会议结束后在MATLAB工作区查看a.b(1).c1
,即使你只是&#34;只有&#34;已更改c2
。
从MEX,您在不了解或访问MATLAB内部管理的情况下查看原始数据存储,因此唯一的安全修改方式是使用mxCreate*
或mxDuplicate*
函数来获取您自己的安全数组,然后您可以随意执行任何操作,并通过plhs
传回MATLAB。
那就是说,我承认在一个实例中滥用in-place modification可以获得显着的性能提升,我可以保证我的数据是独特的和非共享的,但它最多是不受支持的,最坏的是危险的