假设我有一些在独立应用程序中使用的函数 foo
,(即用 mcc -m
编译成可执行文件),它有一个重要的中间结果栏
。通常我在函数完成后不需要这个中间结果,因此它不是返回值。然而,出于开发和调试目的,能够使中间结果可访问是很有用的,我可以通过使用 assignin
将中间结果放入某个调试工作区来实现这一点。
现在的问题是 assignin
在独立编译中是不可能的,如果有 assignin
mcc
会报错> 在代码中。我想做的是仅在代码以交互方式运行时包含 assignin
,而不是在编译为独立应用程序时包含。此外,这会加快速度,因为我在独立应用程序中无论如何都不需要中间结果,因此可以通过不在独立应用程序中执行分配来获得相同的时间和/或内存。在任何其他编程环境中,人们会称之为调试和 Release模式下的编译。
在伪 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 完全忽略 protected 代码块并且不尝试编译它的代码构造,因为无法在独立模式下编译 assignin。
顺便说一句,这不仅对中间结果有值(value),而且对额外的数据收集也很有值(value),额外的数据将在 protected block 中计算并通过 assignin
导出。显然,此类额外数据不应在独立版本中计算,因为它没有任何用处。
matlab 中是否有任何此类代码构造可以实现此目的,或者是否有更好的选择?到目前为止,在开发过程中,我一直在处理注释代码、取消注释和重新注释调试代码。
最佳答案
您可以使用全局调试结构并将变量存储在同名字段中,而不是使用 assignin 来填充调试工作区。所有有效的变量名称也是有效的结构字段名称。您可以使用全局变量来实现它,但最好在函数内使用持久变量。这将适用于已编译或未编译的代码。
首先,有一个定义 Debug模式的函数。
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
然后是一个用于存储调试值的函数,它仅在 Debug模式打开时保留值。
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
调试默认是关闭的,所以在编译版本中会短路,不会累加值。使用 isdebugging(true) 在交互式 Matlab session 中手动启用它。这绕过了检测您是否正在运行部署的问题。这也意味着您可以在编译的应用程序中启用和使用它,如果您想测试编译的代码以查看它在该上下文中的工作方式。您可以使用 GUI 按钮或环境变量来告知已编译的应用启用调试。
isdebugging() 调用可以保护其他代码。但是我不会因为使用 isdebugging() 来保护除日志输出或值累积之外的任何东西而太过分。您不希望调试机制对代码的正确性产生副作用。
另请参阅 Java 的 log4j,将其作为如何将运行时可配置调试输出合并到应用程序中的模型。您可以将其原理应用到 Matlab。
关于debugging - 在独立的 matlab 中调试代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5017542/