gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 07:13:50 25 4
gpt4 key购买 nike

最近,我尝试使用结构变量编写 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]);
}
}

最佳答案

这些地址并非“意外地相同”,而是有意相同,这是由于 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_b2 一样和i_c2 ,如果您查看a.b(1).c1,您就进入了“不可预测的结果”领域。在调用后的 MATLAB 工作区中,它实际上是 10,即使您“仅”更改了 c2 .

从 MEX 中,您查看原始数据存储,而无需了解或访问 MATLAB 的内部管理,因此修改任何内容的唯一安全方法是使用 mxCreate*mxDuplicate*函数来获取您自己的安全数​​组,然后您可以执行任何您想要的操作,并通过 plhs 传回 MATLAB .

也就是说,我承认我滥用了 in-place modification在一种情况下,我可以保证我的数据是唯一的且不共享的,但它充其量不受支持,最坏的情况是完全危险的,从而获得显着的性能提升。

关于c - 结构变量数组中的 mexfunction 变量错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27560226/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com