【问题标题】:How to print C-preprocessor variables like __LINE__ with mexErrMsgTxt() In Matlab MEX如何在 Matlab MEX 中使用 mexErrMsgTxt() 打印 C 预处理器变量,如 __LINE__
【发布时间】:2015-02-20 13:49:28
【问题描述】:

对于调试 Matlab-MEX,这可能会很麻烦,最好有更好的断言能力。在this question about mex-assertions 之后,可以定义一个预处理器makro,它会向Matlab 抛出一个错误并打印一个字符串(主要可以替换mxAssert,它不幸地导致Matlab2011b 崩溃)。

#define myassert( isOK,astr )      ( (isOK) ? (void)0 : (void) mexErrMsgTxt(astr) ) 

打印文件、行号和调用者函数会更好,从下面的示例断言myassert(A=B,"A not B") 引发! This answer 最初的问题指出它们是预处理器变量:

__LINE__,__PRETTY_FUNCTION__, __FILE__

我们如何使用mexErrMsgTxt 打印这些预处理器变量?

问题是,mexErrMsgTxt() 采用 char* 参数,而不是多个输入,例如 printf(const char *format, ...)

目前我的想法仅此而已:

  1. 无法构建函数,因为预处理器变量将具有函数中的值(例如行号)。
  2. 我不可能编写一个可工作的多行预处理器 makro,它从传递的 string astr 创建一个 char 并将其传递给 mexErrMsgTxt()Maybe a solution is along these lines.
  3. hybrid 解决方案具有创建预处理器 makro 的 char 和将其传递给 mexErrMsgTxt() 的函数,感觉不像是好的编码实践。

将指定的错误字符串设为可选会非常好。

【问题讨论】:

    标签: c++ c debugging mex c-preprocessor


    【解决方案1】:

    只要您只使用__FILE____LINE__ 和字符串文字作为消息,连接预处理器标记就可以工作。然后你可以写类似的东西

    #define STRINGIZE_I(x) #x
    #define STRINGIZE(x) STRINGIZE_I(x)
    
    #define myassert(isOK, astr) ( (isOK) ? (void)0 : (void) mexErrMsgTxt(__FILE__ ":" STRINGIZE(__LINE__) ": " astr) )
    

    不幸的是,__PRETTY_FUNCTION__ 不是字符串文字,即使对于那些支持它的编译器也是如此。如果您想使用它(或不太固定的错误消息),您必须动态组装字符串,这意味着类似于

    #define myassert(isOK, astr)                                            \
      do {                                                                  \
        if(!(isOk)) {                                                       \
          std::ostringstream fmt;                                           \
          fmt << "In " << __PRETTY_FUNCTION__ << ", "                       \
              << __FILE__ << ":" << __LINE__ << ": " << (astr);             \
          (void) mexErrMsgTxt(fmt.str().c_str());                           \
        }                                                                   \
      } while(false)
    

    对于 C,对 snprintf 执行相同操作。 (或asprintf。它避免了固定缓冲区长度和长错误消息的问题,并且与__PRETTY_FUNCTION__ 一样可移植)。不管怎样,大致像

    #define myassert(isOK, astr)                                            \
      do {                                                                  \
        if(!(isOk)) {                                                       \
          char buf[ENOUGH_SPACE];                                           \
          snprintf(buf, ENOUGH_SPACE, "In %s, %s:%d: %s",                   \
                   __PRETTY_FUNCTION__, __FILE__, __LINE__, (astr));        \
          buf[ENOUGH_SPACE - 1] = '\0';                                     \
          (void) mexErrMsgTxt(buf);                                         \
        }                                                                   \
      } while(0)
    

    ...必须适当定义ENOUGH_SPACE 的位置(在snprintf 的情况下)。

    【讨论】:

    • 感谢您的回答! ;) 字符串已经是可选的了...mexErrMsgTxt0 前面的 (void) 命令真的有必要吗?还是只是编码练习来澄清没有输出?
    • mexErrMsgTxt 返回void,并且?: 的两个结果操作数必须具有相同的类型,因此在这个构造中是必要的(我从问题中得到了货物)。至于编码练习:如果我自己写,我会使用do { if(!(isOk)) { mexErrMsgTxt(all that stuff); } } while(0),因为stackoverflow.com/questions/154136/…
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 2021-05-25
    • 2020-06-04
    • 2011-07-09
    • 2010-11-26
    相关资源
    最近更新 更多