如何在运行时制作 mex 函数 printf?

Posted

技术标签:

【中文标题】如何在运行时制作 mex 函数 printf?【英文标题】:how can I make a mex function printf while it's running? 【发布时间】:2014-10-09 05:47:32 【问题描述】:

我的 MATLAB 脚本中调用了一个 mex 文件。 mex函数可能需要一段时间才能运行,所以为了防止我的代码“停在那里没有任何输出”,我在mex文件中放了很多printf语句来输出正在处理的数据的一些运行信息。

但是当我调用 mex 函数时,它不会 printf 任何东西并在 int 运行期间停留在那里。最后,在完成它的工作之后,它会printf 我想要的所有信息——不是在它运行的时候,而是完成之后。这不是我想要的。

所以我想知道如何不仅让printf 成为我想要的东西,而且在我想要的时候也让printf 成为。

【问题讨论】:

关闭投票审阅者的注意事项:这个问题已经过大量编辑,现在从 MATLAB MEX 用户的角度来看非常清楚。 @zeakey:你应该接受任何对你有用的答案。 【参考方案1】:

是的,mexPrintf 就是您所需要的。但请注意,命令窗口不会强制刷新它使用的缓冲区,这通常会导致在您的消息打印之前有很长的延迟。如果您在调用 mexPrintf 后开始大量计算,就会发生这种情况。

一种解决方法是使用

mexEvalString("drawnow;")

在每次调用mexPrintf之后。

如果您觉得这不吸引人,您可以创建一个同时调用两者的宏:

#define printfFnc(...)  mexPrintf(__VA_ARGS__); mexEvalString("drawnow;");

这使用可变参数宏__VA_ARGS__。它可能不是标准的一部分,但似乎在 GCC 和 Visual C++ 中。只需拨打printfFnc 就像您拨打printf(或mexPrintf)一样。

【讨论】:

这是官方支持的解决方案。总是有其他方法:) 这在 R2016b 中不起作用。在函数完成之前,输出仍然不可见。有解决办法吗?【参考方案2】:

libmwservices.dll 中有一个未记录的 C++ 函数。它显然会刷新输出缓冲区。这是一个例子:

test_mex_print.cpp

#include "mex.h"

#pragma comment(lib, "libmwservices.lib")
extern bool ioFlush(void);

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

    for(int i=0; i<100000; i++) 
        mexPrintf("%d\n", i);
        ioFlush();
    

直接编译为:mex -largeArrayDims test_mex_print.cpp

【讨论】:

使用 gcc 在 linux 上构建,将其附加到“mex”命令:-lmwservices -lmwbuiltins 这是一个了不起的发现,非常有用!您是如何在库中找到该函数的? @DarkCell dumpbin.exe /DLL 可用于列出导出的函数,或使用Dependency Walker 之类的工具。 Linux 也有类似的工具(objdumpnmldd 等) @Amro 是的,我知道这样的工具,但是在 Matlab 中有很多包含的库,其中包含很多符号,名称部分非常神秘,您发现一个完全可以执行的函数似乎很了不起你想要什么,你甚至找到了没有头文件的正确数据类型。赞一个!【参考方案3】:

您可以使用mexPrintf

*
* mex equivalent to MATLAB's "disp" function
*/
extern int mexPrintf(const char *fmt, /* printf style format */
                     ... /* any additional arguments */);

【讨论】:

【参考方案4】:

我遇到了与 OP 相同的问题,在 mex 文件完成运行之前, mexPrintf() 不会打印任何输出。此外, mexEvalString("drawnow;");似乎没有解决问题,或者至少我的设置没有解决(MATLAB2015b 和 C++11 MEX 代码的 64 位 MinGW 编译器)。

但是,使用 mexEvalString("pause(.001);");在 mexPrintf() 确实修复它之后。我花了一些反复试验才弄清楚,所以我希望这对将来的参考有用。

TLDR:使用 mexEvalString("pause(.001);");

【讨论】:

【参考方案5】:

printf 打印到标准输出,不是 matlab 屏幕。 (默认隐藏,最后收集/显示)

试试 mexprintf():

http://www.mathworks.co.uk/help/matlab/apiref/mexprintf.html

在 C MEX 文件中,您必须调用 mexPrintf 而不是 printf 才能显示字符串。

C Syntax

#include "mex.h"
int mexPrintf(const char *message, ...);

Arguments

message
String to display. In C, the string can include conversion specifications, used by the ANSI® C printf function.

...
In C, any arguments used in the message. Each argument must have a corresponding conversion specification.

Returns
Number of characters printed including characters specified with backslash codes, such as \n and \b.

【讨论】:

其实如果你看mex.h,头文件有#define printf mexPrintf以防万一......所以没有区别。

以上是关于如何在运行时制作 mex 函数 printf?的主要内容,如果未能解决你的问题,请参考以下文章

在八度音程中运行 matlab 项目时,mex 函数未定义错误

MATLAB + Mex + OpenCV:链接和编译正确,但在运行时找不到库

在八度音程中运行matlab项目时,mex函数未定义错误

Matlab MEX-函数副作用

如何使用用户预定义的数据设置 mwArray?是不是可以混合使用 Matlab 库编译器和 mex 运行时?

并行运行 MEX 文件时的分段错误