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

アサインインを使用してデバッグワークスペースにデータを入力する代わりに、グローバルデバッグ構造体を使用して、同じ名前のフィールドに変数を格納することができます。有効な変数名はすべて、有効な構造体フィールド名でもあります。これはグローバル変数を使用して実装できますが、関数内の永続変数を使用した方がよいでしょう。これは、コンパイルされたコードまたはコンパイルされていないコードで機能します。

まず、デバッグモードを定義する関数を用意します。

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に適用できます。

于 2011-02-16T16:07:37.290 に答える
1

関数isdeployedを使用します。isdeployedは、MCRで実行する場合はtrue、MATLABで実行する場合はfalseです。

編集:もちろん、これはコンパイルの問題を解決しません。あなたはassigninの代わりを見つけなければならないかもしれません。

于 2011-02-16T14:33:50.300 に答える