假设我有一个在独立应用程序中使用的函数foo
(即编译成具有mcc -m
的可执行文件,)具有重要的中间结果bar
。通常我在完成函数后不需要这个中间结果,因此它不是返回值。但是,出于开发和调试目的,能够访问此中间结果非常有用,我可以使用assignin
将中间结果放入某个调试工作区。
现在的问题是,在独立编译中assignin
是不可能的,如果代码中有mcc
,assignin
会抱怨错误。我想做的是仅在代码以交互方式运行时包含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中是否有任何这样的代码构造可以实现这一点,还是有更好的选择?到目前为止,我一直在处理评论代码,取消注释并重新调试调试代码,就像我在开发过程中一样。
答案 0 :(得分:2)
您可以使用全局调试结构并将变量存储在同名字段中,而不是使用assignin来填充调试工作区。所有有效的变量名称也是有效的struct字段名称。您可以使用全局变量实现此功能,但在函数内使用持久变量可能会更好。这将在编译或非编译代码中工作。
首先,有一个定义调试模式的函数。
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
默认情况下禁用调试,因此它会在编译版本中短路而不会累积值。使用isdebugging(true)在交互式Matlab会话中手动启用它。这绕过了检测您是否正在部署的问题。它还意味着您可以在已编译的应用程序中启用和使用它,如果您想测试已编译的代码以查看它在该上下文中的工作方式。您可以使用GUI按钮或环境变量来告知已编译的应用程序启用调试。
isdebugging()调用可以保护其他代码。但是,除了日志输出或值累积之外,使用isdebugging()来保护任何东西都不会让我感到沮丧。您不希望调试机制对代码的正确性产生副作用。
另请参阅Java的log4j,作为如何在应用程序中合并运行时可配置调试输出的模型。您可以将其原则应用于Matlab。
答案 1 :(得分:1)
使用功能isdeployed。 isdeployed在MCR中运行时为true,在MATLAB中运行时为false。
编辑:当然,这并不能解决编译问题。您可能必须找到assignin的替代品。