我可以通过mex文件mexAtExit处理程序检测MATLAB终止吗?

时间:2015-02-26 08:38:38

标签: matlab mex

TL;博士

Matlab .m文件中是否有任何方法可以检测到Matlab终止正在进行中?


我有一个非托管库,它提供了我产品的界面。我已经使用mex文件为Matlab包装了它。所以我的非托管库作为Windows DLL存在。我有一个包含它的mex文件。反过来,我有一个Matlab类的集合,在包装mex文件的各种.m文件中实现。到目前为止,所有这些都很出色。

我最近在Matlab关机期间意识到了一个问题。一些Matlab类包装非托管对象。这些非托管对象在不再需要时需要销毁。因此,我为包装非托管对象的Matlab类实现delete函数,并调用mex文件来销毁对象。显然,mex文件只是将这些销毁调用转发给非托管库。再次,这一切都很好。

当Matlab关闭并且用户的工作区包含包装非托管对象的Matlab对象时,会出现问题。不幸的是,Matlab卸载mex文件,然后销毁工作区中的对象。接下来会发生的是delete函数执行调用mex文件的函数。其中重新加载刚刚卸载的mex文件。现在,销毁非托管对象的尝试会导致运行时错误,因为我的库必须重新加载。

由于要在销毁工作空间对象之前卸载mex文件,我别无选择,只能在该场景中跳过删除非托管对象。它不是内存泄漏或实际上是一个问题,因为该过程正在终止。但是,我确实需要检测该进程是否正在终止。这导致了问题,如何做到这一点。

我知道finish.m终止文件,但由于我提供了一个库,因此我无法控制它。用户控制他们的终止文件,因此我排除了该选项。我甚至不知道它是否在合适的时间运行,即在工作空间对象被销毁之前运行。

我使用mexAtExit构建了一个正常运行的解决方案。在mex文件初始化中,我像这样调用mexAtExit

mexAtExit(atExit);

atExit功能是:

void atExit(void)
{
    mexCallMATLAB(0, NULL, 0, NULL, "mylib.atExit");
}

ofx.atExit在Matlab代码中,并按照以下方式实现:

methods(Static)

  function atExit
    mylib.mexHasUnloaded(true);
  end

  function result = mexHasUnloaded(varargin)
    global mexHasUnloadedGlobalVar;
    if isempty(mexHasUnloadedGlobalVar)
      mexHasUnloadedGlobalVar = false;
    end
    if nargin > 0
      mexHasUnloadedGlobalVar = varargin{1};
    end
    result = mexHasUnloadedGlobalVar;
  end

  ....

end

delete函数然后检查mexHasUnloaded,如下所示:

function delete(self)
  if ~mylib.mexHasUnloaded
    mylibMex(mylib.mexDestroyObject, self.handle);
  end
end

虽然这似乎有用,但我对此并不满意。

  • 我真的只能从mex文件中检测到Matlab终止吗?我想直接在.m文件中检测到这一点,感觉应该是可能的。有可能吗?
  • 我真的需要使用这样的全局变量吗?我不能找到更好的方式来照顾这个状态吗?我尝试使用persistent变量,但这就像hacky一样无效。 persistent变量在终止期间的某个时刻重新初始化,这意味着mexHasUnloadedfalse之前设置为true之后开始返回{{1}}。
  • 或者我的问题有不同的解决方案吗?在删除工作区对象之后,我可以强制我的mex文件保持加载状态吗?

1 个答案:

答案 0 :(得分:3)

它是否适用于mexLock()您的MEX文件,以便它不会被卸载,因此delete方法可以在关机时做正确的事情?