Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以通过mex文件MEXATEXT处理程序以外的方式检测MATLAB终止吗?_Matlab_Mex - Fatal编程技术网

我可以通过mex文件MEXATEXT处理程序以外的方式检测MATLAB终止吗?

我可以通过mex文件MEXATEXT处理程序以外的方式检测MATLAB终止吗?,matlab,mex,Matlab,Mex,tl;dr 在Matlab.m文件中是否有任何方法可以检测到Matlab正在终止 我有一个非托管库,它为我的产品提供了一个接口。我已经用一个mex文件为Matlab包装了它。因此,我的非托管库作为Windows DLL存在。我有一个mex文件可以包装它。反过来,我有一个Matlab类的集合,这些类在包装mex文件的各种.m文件中实现。到目前为止,一切都很顺利 我最近意识到Matlab关闭期间出现了一个问题。一些Matlab类包装非托管对象。当不再需要这些非托管对象时,需要销毁它们。因此,我为包

tl;dr

在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");
}
而x.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
function delete(self)
  if ~mylib.mexHasUnloaded
    mylibMex(mylib.mexDestroyObject, self.handle);
  end
end
delete
函数然后检查
mexhaunloaded
,如下所示:

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
function delete(self)
  if ~mylib.mexHasUnloaded
    mylibMex(mylib.mexDestroyObject, self.handle);
  end
end
虽然这似乎有效,但我对它一点也不满意

  • 我真的只能从mex文件中检测Matlab终止吗?我想直接在.m文件中检测到这一点,感觉这应该是可能的。可能吗
  • 我真的需要使用这样的全局变量吗?我不能找到更好的办法来照顾这个州吗?我试着使用一个
    持久的
    变量,但这也太过粗糙,不起作用。
    persistent
    变量在终止期间的某个点重新初始化,这意味着
    mexHasUnloaded
    在先前设置为
    true
    后开始返回
    false
  • 或者我的问题有不同的解决方案吗?在删除工作区对象之前,是否可以强制mex文件保持加载状态

它对MEX文件
mexLock()
有效吗,这样它就不会被卸载,这样
delete
方法就可以在关机时做正确的事情了吗?

好的,我的第一次尝试似乎表明它达到了预期的效果。我很高兴永久加载mex文件。我会做更多的测试。非常感谢。这确实解决了我的问题,尽管方式与我最初设想的不同。我把问题更新了一点,以便接受你的回答。非常感谢。您能否确认无法从m文件中检测关机?据我所知,唯一记录在案的检测关机的
.m
文件方法是
finish.m
——正如您所观察到的,它不适合图书馆作者。