Matlab MEX-函数副作用

Posted

技术标签:

【中文标题】Matlab MEX-函数副作用【英文标题】:Matlab MEX-function side effect 【发布时间】:2021-09-21 22:29:27 【问题描述】:

MEX 是 Matlab 用来在 Matlab 中运行 C/C++ 函数的框架(运行速度更快)。在the documentation 它说:

输入参数(在 prhs 数组中)是只读的;不要在您的 MEX 文件中修改它们。更改输入参数中的数据可能会产生不希望的副作用。

这是否只是一个警告,即更改作为指针传递的变量将如何在函数外部更改该变量(与 Matlab 的工作方式不同),或者是否有更微妙的方式可以弄乱 Matlab/MEX 界面?

我问的原因是我特别希望 MEX 函数真正修改参数。

【问题讨论】:

正确的做法是将它们返回到左侧 (plhs)。没有理由更改输入参数值,这不是语言的设计方式,因此不需要的副作用尽可能明确。你可以用锤子做饭,但“不良副作用”是最好的告诉你可能发生的事情,因为它根本不是为此而设计的。 上述文档与 C mex API 相关,但在较新的 C++ mex API 中可以修改输入参数。 在我的愿望清单上(我知道永远不会发生):一个官方 API 函数,用于告诉您一个变量是否与另一个变量共享,以便您可以在运行时判断就地操作是否安全否则会有副作用。 【参考方案1】:

MATLAB 使用延迟复制,这意味着当您执行 b = a 时,变量 b 指向与变量 a 相同的数据,即使在语义上您进行了复制。例如,当您现在执行a(1) = 0 时,您修改变量a,MATLAB 先进行复制,这样变量b 就不会受到赋值的影响。这显然节省了大量内存,因为在未修改副本的地方制作了许多副本。

例如,当调用一个函数时,输入变量的副本被放置在函数的工作区中。 sum(a) 导致a 的(惰性)副本在函数内部可用。如果函数不需要修改变量,则避免复制。如果它确实修改了它,则制作一个副本,以便调用者不会更改 a

MEX 文件的工作方式相同,只是 MATLAB 无法检测您是否修改了输入变量,因此它无法在您修改之前进行复制。因此发出警告。您需要调用 mxDuplicateArray() 来复制数组并对新副本进行更改。

文档警告的副作用是调用者工作区中的变量以及与之共享数据的所有变量都被修改了。例如,假设您创建了一个修改输入的 MEX 文件函数 modifyIn,然后:

a = zeros(500);
b = a;
% much later in the code…
modifyIn(b); % update b the way I want!

很意外还会修改a


This blog post on Undocumented MATLAB 更详细地讨论了这个问题,并讨论了 mxUnshareArray(),这是一个未记录的函数,只有在您对可能发生的崩溃和其他可能发生的问题感到非常满意时才应该使用它。未记录的函数的保质期有限。

【讨论】:

我明白了,谢谢。 @berala 查看答案底部的编辑。 天哪,博客拥有,谢谢!

以上是关于Matlab MEX-函数副作用的主要内容,如果未能解决你的问题,请参考以下文章

Clear的matlab

Matlab mex 选项未更新

SLIC超像素分割slicmex源代码在windows下matlab中mex出错的修正

SLIC超像素分割slicmex源代码在windows下matlab中mex出错的修正

如何在从 Matlab 调用的 mex 函数中使用 Matlab 引擎

matlab多次调用mex函数后没有响应