2011-02-16 17 views
3

說我有一些功能foo用於獨立的應用程序,(即編譯成一個可執行文件與mcc -m,),其中有一個重要的中間結果bar。正常情況下,函數完成後我不需要這個中間結果,因此它不是返回值。但是,對於開發和調試目的,能夠使這個中間結果可訪問是有用的,我可以通過使用assignin將中間結果放入某個調試工作空間來實現。在獨立的matlab中的調試代碼

現在問題是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中是否有任何這樣的代碼構造可以完成這個任務,還是有更好的選擇?到目前爲止,我剛剛在開發過程中一直在討論註釋代碼,取消註釋和推薦調試代碼。

回答

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 

默認情況下,調試功能是禁用的,所以它會在編譯版本中短路,而不會累積值。使用isdebugging(true)在交互式Matlab會話中手動啓用它。這繞過檢測您是否正在運行部署的問題。這也意味着如果您想測試編譯後的代碼以查看它在該上下文中的工作方式,則可以在已編譯的應用程序中啓用並使用它。您可以使用GUI按鈕或環境變量來告知已編譯的應用程序以啓用調試。

isdebugging()調用可以防止其他代碼。但是我不會因爲使用isdebugging()來防止除日誌輸出或值累積之外的任何事情而過度使用。您不希望調試機制對代碼的正確性產生副作用。

還可以看看Java的log4j,作爲如何在應用程序中集成運行時可配置調試輸出的模型。您可以將其原理應用於Matlab。

1

使用功能isdeployed。在MCR中運行時isdeployed爲true,在MATLAB中運行時爲false。

編輯:當然,這並沒有解決編譯的問題。您可能必須找到替代assignin ..

+0

不幸的是,似乎這個函數在我的古老版本的matlab(6.1.0.450)中還沒有提供,但是`mcc`對任何這樣的ifblock都很聰明並且完全忽略它,或者它會嘗試編譯`assignin `代碼,因此編譯失敗。 – wich 2011-02-16 14:53:29