【问题标题】:Stop mex function (C) without closing MATLAB在不关闭 MATLAB 的情况下停止 mex 函数 (C)
【发布时间】:2019-06-20 09:21:26
【问题描述】:

我想在检测到 NaN 后停止执行 C 代码并使用 mexWarnMsgTxt 将错误消息发送到 MATLAB。

C 代码通过 mex 文件从 MATLAB 执行。我尝试使用 abort() 和 exit() 这确实杀死了 c 程序,但也杀死了 MATLAB(我猜是因为它是这里的调用进程。)

#include "mex.h"
#include "matrix.h"


for (int i = 0; i <= 5; i++)
       {
           if (mxIsFinite(out[i])) {

           }
           else if (mxIsInf(out[i])) {
               char *err_msg = malloc(max_len_err_msg);
               snprintf(err_msg, max_len_err_msg, "Inf detected in file %s at line %d", __FILE__, __LINE__);
               mexWarnMsgTxt(err_msg);
               abort();
               //free(err_msg);
               //abort(1);
               /* NOTE: Test for NaN is here for illustration only.  If a double
                * is not finite and is not infinity, then it is a NaN */

           }
           else if (mxIsNaN(out[i])) {
               char *err_msg = malloc(max_len_err_msg);
               snprintf(err_msg, max_len_err_msg, "NaN detected in file %s at line %d", __FILE__, __LINE__);
               mexWarnMsgTxt(err_msg);
               abort();
               //free(err_msg);

           }
       }

我只希望我的 mexFunction 停止但不终止 Matlab。

【问题讨论】:

  • 您是否尝试过使用returnbreak

标签: c matlab mex


【解决方案1】:

mex 函数是普通的 C 函数,所以要提前离开函数,只需使用 return

如果您分配的资源需要手动清理,C 中已建立的习惯用法是使用goto cleanup;(这是goto 的少数(如果不是唯一的话)可接受和普遍接受的用法之一):

void mexFunction(
    int nlhs, mxArray *plhs[],
    int nrhs, const mxArray *prhs[]
) {
    for (int i = 0; i <= 5; i++) {
        if (mxIsInf(out[i])) {
            char *err_msg = malloc(max_len_err_msg);
            snprintf(err_msg, max_len_err_msg, "Inf detected in file %s at line %d", __FILE__, __LINE__);
            mexWarnMsgTxt(err_msg);
            free(err_msg);
            goto cleanup;
        } else if (mxIsNaN(out[i])) {
            char *err_msg = malloc(max_len_err_msg);
            snprintf(err_msg, max_len_err_msg, "NaN detected in file %s at line %d", __FILE__, __LINE__);
            mexWarnMsgTxt(err_msg);
            free(err_msg);
            goto cleanup;
        }
        …
    }

cleanup:

    // Perform cleanup here.
}

(请注意,在此代码中,err_msg 清理是在其自身范围内执行的,而不是全局清理。)

但在不进行清理的情况下,goto 语句是不必要的,可以用return 代替。

【讨论】:

  • 我会在清理例程中写什么?
  • @hcl734 这完全取决于您需要执行的清理工作,而这又取决于您分配的需要手动管理的资源。我不能告诉你。
【解决方案2】:

我当前的解决方案是在 C 中定义一个全局变量 abort_flag,如果发生错误,则将其设置为 1,并基于此中断我的所有循环并从函数返回。 有点“手动”但有效:

int  abort_flag = 0;
// to use in other file insert into header: extern int abort_flag;

// in the NaN case (see above)
abort_flag = 1;

// in the loops
if (abort_flag==1) { break; };

// in the functions
if (abort_flag==1) { return; };

【讨论】:

  • 标志和break的目的是什么?为什么不直接return
  • 该标志是 imo 所必需的,以告知包含上述 for 循环的函数的调用函数也终止(此处显示的 for 循环在另一个 for 循环中运行的简称)。这不是实际代码,只是为了演示我在其他地方插入的内容,很抱歉造成混淆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
相关资源
最近更新 更多