如何从 C/C++ 中止 MATLAB m 文件函数?

Posted

技术标签:

【中文标题】如何从 C/C++ 中止 MATLAB m 文件函数?【英文标题】:How do I abort a MATLAB m-file function from C/C++? 【发布时间】:2009-09-24 09:48:39 【问题描述】:

我将一个 MATLAB 项目部署到一个 DLL 中,以便从 C++ 中调用,它工作得很好。快乐的日子。

但是当用户要求取消操作时会发生什么?

我尝试创建一个名为UserAbortedglobal 变量。在 MATLAB 中运行 long 函数之前,我将其初始化为 0。我还写了以下两个函数:

function AbortIfUserRequested
    global UserAborted

    if (UserAborted == 1)
        error('User Abort');
    end
end

function UserAbortLongFunction
    global UserAborted

    UserAborted = 1;
end

我在 long 函数的每次循环迭代中调用 AbortIfUserRequested。我还导出了UserAbortLongFunction

我预计在调用UserAbortLongFunction 后不久,long 函数会调用AbortIfUserRequested,并引发错误。

相反,long 函数一直运行到最后,只有 然后 的值才会更改 UserAborted

我想做的就是在用户要求我时中止那个长函数!有什么办法吗?

【问题讨论】:

Matlab 从 M 代码的角度来看是单线程的。您如何调用 UserAbortLongFunction? UserAbortLongFunction 是在 long 操作仍在运行时返回还是阻塞? UserAbortLongFunction 的调用不会阻塞,并且会立即返回。我不确定这是 M 代码问题;我尝试在长函数运行时从 MATLAB 中的命令行执行 UserAbortLongFunction。我还让 long 函数在代码中的许多点打印UserAborted 的值作为其操作的一部分。它一直保持为 0 直到 long 函数结束,在调用 UserAbortLongFunction 很久之后。 【参考方案1】:

尝试在 AbortIfUserRequested 中调用 DRAWNOW 函数。尽管 Matlab 是单线程的(从 API 的角度来看),但它确实允许中断。我通过使用纯 M 代码调用此函数取得了成功,否则用户输入(如 Ctrl-C)会被锁定。

【讨论】:

【参考方案2】:

Matlab 需要提供回调函数来显示执行进度并可能暂停它。谷歌搜索显示很多人想要这个,但 Mathworks 没有实现。

【讨论】:

嗯...好点。但是你知道,MATLAB 确实有几个回调函数——用于报告标准输出和标准错误。我刚刚做了disp('PROGRESS=33%) 并调用了用于处理标准错误的回调函数。然后我只是解析了这些字符串,并在 C++ GUI 中显示了进度。但你是对的 - 没有适当的支持。【参考方案3】:

Matlab 的单线程特性可能会阻止对全局变量值的更新在第一个函数执行时传播。您可以尝试将 abort 标志粘贴到 Java 对象(如 HashMap)中,以获得间接层。由于 Java 对象是通过引用传递的,对其状态的更新可能会立即可见,而无需更改 Matlab 变量本身。

这是一个 sn-p 这样做。 (抱歉,我没有 Matlab 编译器许可,无法在已部署的 DLL 中对此进行测试。)

function AbortIfUserRequested
    global SharedState
    if SharedState.get('UserAborted')
        error('User Abort');
    end
end

function UserAbortLongFunction
    global SharedState
    SharedState.put('UserAborted', 1);
end

function InitUserAbort
    global SharedState
    SharedState = java.util.Collections.synchronizedMap(java.util.HashMap());
    SharedState.put('UserAborted', 0);
end

Matlab 应用程序数据也通过引用有效地传递。将 abort 标志放在 appdata 而不是全局变量中也可能有效。如果您的库与 Matlab GUI 一起使用,您可以将应用程序数据放在其图形句柄而不是全局句柄 0 上。如果可以的话,这将比 Java 对象更符合 Matlab 的习惯。

function AbortIfUserRequested
   if getappdata(0, 'UserAborted')
      error('User Abort');
   end
end
function UserAbortLongFunction
   setappdata(0, 'UserAborted', 1);
end

【讨论】:

以上是关于如何从 C/C++ 中止 MATLAB m 文件函数?的主要内容,如果未能解决你的问题,请参考以下文章

matlab 中如何打开文件

C++调用matlab数学函数问题

C/C++程序通过动态链接库调用MATLAB程序

在matlab中怎么直接调用函数

MATLAB mex文件

如何给matlab coder装license