3

假设我有一些foo在独立应用程序中使用的函数(即用mcc -m, 编译成可执行文件),它具有重要的中间结果bar。通常在函数完成后我不需要这个中间结果,因此它不是返回值。然而,对于开发和调试目的,能够使这个中间结果可访问是很有用的,我可以通过assignin将中间结果放在某个调试工作区中来做到这一点。

现在的问题是,assignin在独立编译中是不可能的,mcc如果代码中有一个错误,就会报错assignin。我想做的是assignin仅在代码以交互方式运行而不是在编译为独立应用程序时包含。此外,这会加快速度,因为我在独立应用程序中无论如何都不需要中间结果,因此可以通过不在独立应用程序中执行分配来同时处理时间和/或内存。在任何其他编程环境中,人们都会将其称为调试和发布模式下的编译。

在伪matlab中:

function res = foo()
  bar = some complicated formula
  if ~standalone
    assignin('debug', 'foo_bar', bar)
  end
  res = some complicated formula involving bar

问题是我不知道如何表达if ~standalone,首先我不知道如何测试是否处于独立模式,但更关键的是,这需要一些代码结构,实际上导致 mcc 完全无视被保护的代码块,不要尝试编译它,因为在独立模式下无法编译assignin。

顺便说一句,这不仅对中间结果很有价值,而且对额外的数据收集也很有价值,额外的数据将在受保护的块中计算并通过assignin. 显然,此类额外数据不应在独立版本中计算,因为它没有任何用途。

matlab 中是否有任何这样的代码结构可以做到这一点,还是有更好的选择?到目前为止,在开发过程中,我一直在处理注释代码、取消注释和重新注释调试代码。

4

2 回答 2

2

您可以使用全局调试结构并将变量存储在同名字段中,而不是使用 assignin 填充调试工作区。所有有效的变量名称也是有效的结构字段名称。您可以使用全局变量来实现这一点,但使用函数内的持久变量可能会更好。这将适用于已编译或未编译的代码。

首先,有一个定义调试模式的函数。

function out = isdebugging(value)
%ISDEBUGGING Get or set the global debugging state

persistent state
if isempty(state)
    state = false;
end

switch nargin
    case 0 % Getter
        out = state;
    case 1 % Setter
        state = value;
end

然后是一个用于存储调试值的函数,该函数仅在调试模式打开时保留值。

function out = debugval(action, name, value)
%DEBUGVAL Stash values for debugging

persistent stash
if isempty(stash)
    stash = struct;
end

% Short-circuit when not in debugging mode to save space
if ~isdebugging()
    return;
end

switch action
    case 'get'
        out = stash.(name);
    case 'getall'
        out = stash;
    case 'set'
        stash.(name) = value;
    case 'list'
        out = fieldnames(stash);
    case 'remove'
        stash = rmfield(stash, name);
    case 'clear'
        stash = struct;
end

默认情况下禁用调试,因此它将在编译版本中短路并且不会累积值。在您的交互式 Matlab 会话中使用 isdebugging(true) 手动启用它。这绕过了检测您是否正在运行已部署的问题。这也意味着您可以在已编译的应用程序中启用和使用它,如果您想测试已编译的代码以查看它在该上下文中的工作方式。您可以使用 GUI 按钮或环境变量来告诉已编译的应用程序启用调试。

isdebugging() 调用可以保护其他代码。但是我不会因为使用 isdebugging() 来保护除日志输出或值累积之外的任何东西而过于激动。您不希望您的调试机制对代码的正确性产生副作用。

还可以查看 Java 的 log4j 作为如何在应用程序中合并运行时可配置调试输出的模型。您可以将其原理应用于 Matlab。

于 2011-02-16T16:07:37.290 回答
1

使用函数isdeployed。isdeployed 在 MCR 中运行时为真,在 MATLAB 中运行时为假。

编辑:当然,这并不能解决编译问题。您可能必须找到一个替代assignin..

于 2011-02-16T14:33:50.300 回答