MATLAB コードを使用した C コードの生成クイックスタートガイド (R2012a) 最初のスタンドアロン C コードの生成 スタンドアロン C コードを生成するには MATLAB Coder のペインを [ ビルド ] に切り替えて [C/C++ スタティックライブラリ ] [C/C++ ダイナミックライブラリ ] または [C/C++ 実行ファイル ] のいずれかを選択しま MATLAB Coder を使用することで MATLAB コードから C コードを生成できま MATLAB 内での動作に必要なインターフェイスが含まれるスタンドアロン ANSI-C コードまたは C コードを コンパイル済み MEX ファイルとして生成できま本クイックスタートガイドは スタンドアロン ANSI-C コードの生成方法について説明しま規則に準拠した MATLAB コードの記述方法については MATLAB Coder 用 MATLAB コードの準備 : クイックスタートガイド [1] を参照してください スタティックライブラリ ダイナミックライブラリ 実行 ファイルはどう違うのでしょうか? 生成される C コードに関する限り 違いはありません スタンドアロン C コードの生成手順 スタンドアロン C コードを生成する場合 最初の手順として必ず MEX ファイルを生成しまそのファイルの動作を MATLAB 上で確認してから スタンドアロン C コードを生成しま MEX ファイルにはさまざまなチェックが含まれているため 実行時エラーの検出と修正をより簡単に行うことができま詳細については [1] を参照してください MEX ファイルの生成と動作の検証 [1] 最初のスタンドアロン C コードの生成 外部 C プロジェクトにおいて生成された C コードの理解 生成された C コードのカスタマイズ 生成された C コードの実装 スタティック / ダイナミックライブラリ 実行ファイル MATLAB Coder は C 言語ベースのプロジェクトにおいてリンク可能なスタティック / ダイナミックライブラリをビルドしま場所 : codegen/lib/< 最上位レベル名 > (dll) メイン関数を指定する必要がありまその上で MATLAB Coder は生成されたコードを呼び出す実行ファイルをビルドしま場所 : codegen/exe/< 最上位レベル名 > 1
生成された C コードの理解 コメント元になった MATLAB コードを C コード内にコメントとして追加しておくと その C コードの由来をより簡単に理解できることがよくありま [ 詳細設定 ] [ コード外観 ] を選択 C コードのカスタマイズ より効率的な C コードを生成するベストプラクティスを次に示しま メモリの割り当て MATLAB Coder では配列は 3 つのタイプに区別されま 固定サイズの配列 ( 例 : 12 行 3 列 ) 最大サイズが既知でありサイズが不明の配列 ( maxsize arrays ) サイズがまったく不明の配列 ( 最大サイズが不明 ) MATLAB Coder ではメモリは常にスタック上に割り当てられる スタックに空きがない場合は静的メモリとして割り当てられる サイズがまったく不明の配列がコードに含まれていない場合は動的メモリ割り当てを使用しないように選択可能 動的割り当ては すべての配列が可変サイズの場合 または次の手順で指定したサイズより大きい配列のみに使用される [ 詳細設定 ] [ メモリ ] を選択 ( 下図参照 ) サイズがまったく不明の配列のメモリへの割り当ては 実行時に常に発生 (emxensurecapacity の呼び出しによる動的なメモリ割り当て ) すべての配列にサイズの上限があることを確認する ( 該当する場合 ) 必要に応じて配列のサイズ情報を追加しま例 : assert(n < 25); y = zeros(1,n); 別のベストプラクティスとして後述の インデックスの最適化 も参照してください 生成されたコードが参照により引数を渡すことを確認する C では引数は常に参照により渡されま場合によっては MATLAB Coder は変数をサブ関数に渡す前にそのコピーをローカルに作成しておく必要が生じま ヒント : インプレース構文 a = foo(a) を呼び出し側と関数宣言の両方で使用すれば ローカルでコピーを作成する必要はなくなりま 2
x = foo(x,b) y = foo(x,b) MATLAB Coder はこれが空にならないことを認識できないため :1 として入力しま function a = foo(a,b). 入出力名が呼び出し側と関数宣言の両方で同一 MATLAB Coder は x のローカルコピーを作成する必要がなく これを参照により正しく渡す function a = foo(a,b). 論理配列のインデックスを控えめに使用する 呼び出し側で入出力変数に 2 つの異なる名前を使用 したがって foo への呼出し後に変数 x および y の両方が存在する MATLAB Coder はメモリをコピーしなければならない 論理配列インデックスとは 配列のサブ要素の操作を論理インデッ クスに基づいて実行する機能でたとえば 次によって 255 より 大きいすべての要素を切り取ることができま x(x>255) = 255; 通常は次のように書き換えることで より優れたコードになりま for ii=1:numel(x), if (x(ii)>255), x(ii) = 255; end, end インデックスの最適化 MATLAB Coder では固定長 10 をもつ (i:i+9) は認識されない可能性が ありまこれを i + (0:9) と書き換えることで MATLAB Coder に必 要な情報を与えることができま スカラー入力の強化 MATLAB Coder では x がスカラーであることを認識できない場合がありまたとえば a は常に少なくとも 1 つの正の要素をもつと認識されまつまり x = find(a>0, 1,'first') はスカラーですが スカラー入力を強化するには この行を次のように変更しま x = find(a>0, 1,'first'); x = x(1); 外部 C プロジェクトへのコードの実装 使用するファイル すべての.c および.h ファイルを対象ディレクトリから取得します ( スタティックライブラリの例 : codegen/lib/< 最上位レベル名 >) た いていの場合 すべてのファイルで処理が必要ということになりま メモリのレイアウト MATLAB の行列順序では列が優先されま 2 次元行列の連続要素が 1 つの列の要素にそれぞれ対応しま一方 C 言語は行優先で MATLAB Coder が生成する C コードは MATLAB の動作を模倣しま そのため 入力 ( 出力の場合も ) 引数に複数次元 (2 次元以上 ) の行列 がある場合 外部 C のテストベンチに一致するよう入力 ( または出 力 ) の転置が必要になる場合がありま 引数の型 入力引数および返り値は 以下の C 関数に対応しま 固定サイズ配列 最大サイズ配列 ( 動的割り当てはしない ) 動的に割り当てら 配列へのポインター : x[10] 実際の実行時の配列サイズをもつ配列へのポインター : x_data[10] および x_sizes[2] emxarrays 生成された.h ファイルで定義され 3
れた配列 よくある質問と答え Embedded Coder が必要でしょうか? る特別な型 MATLAB Coder はこれらの配列の作成 破棄を行う補助関数を提供していま詳細については " 原子 " デモを次の手順にしたがって ドキュメンテーションから参照してください [MATLAB Coder] [ デモ ] [MATLAB コードからの C コードの生成 ] で [ 原子のシミュレーションへの動的なメモリ割り当ての使用 ] を選択 Embedded Coder を使用して スタンドアロンのターゲット用に生成 された C コードをカスタマイズできま Embedded Coder の主な特 長は次に示す機能で - 組み込みターゲットに応じた固有の置き換え関数 (TFL) の絞 り込み - 特定ターゲット用のコード生成 (TI DSP) および IDE とのコシ ミュレーション - 再入可能コードの生成 - 変数の名前ルールの定義などのコードスタイルのカスタマ イズ コマンドラインからの実行コード生成およびすべてのオプションの設定はコマンドラインから行うことができま codegen と coder.config を参照してください 複数の関数のコード生成を行う場合の関数名の競合について複数の関数について個々にコード生成を行う場合 MATLAB Coder は 名前は同じでもいくつかのサブ関数の動作が異なる C 関数を生成する場合がありまこれは ファイルをマージしてすべての関数を 1 つのディレクトリに入れようとした場合 競合を招く可能性がありま 解決法 : 複数の関数に対して同時にコードを生成する場合 MATLAB Coder は設計の他の全部位について認識した上で C コードを生成し クラッシュを回避しまそのまま " 複数のエントリポイントファイル " 機能を使うことで 複数の上位レベル関数がプロジェクトに定義付けられま ファイル I/O サポートについて MATLAB Coder では load や fopen を直接にはサポートしていません 一部のファイル入出力に対する直接サポート ( オーディオおよびビデオファイルリーダー System object) については 汎用ファイルからの読み取りおよび書き込み方法の例として coder.opaque の例をご確認ください ターゲット固有ライブラリの使用 MATLAB Coder では個々のターゲットに合わせた実装により 演算子や関数の置き換えが行われまこの機能については ターゲット関数ライブラリ (TFL) の項目の下で説明されていままた ご利用の際には Embedded Coder が必要で 4
再入可能コード / スレッドセーフなコードの生成この機能を利用する場合は Embedded Coder が必要で [ 詳細設定 ] [ メモリ ] を選択してください C++ コードの生成 MATLAB Coder が生成するのは常に C コードで C++ オプションを選択している場合でも MATLAB Coder は C++ コンパイラによってコンパイル可能な.cpp 拡張子の C コードを生成しま [ 詳細設定 ] [ すべての設定 ] [ 言語 ] で [C++] を選択してください 便利な関数 詳細についてはドキュメントをご覧ください coder.ceval 既にもっている外部 C 関数を生成された C コードから呼び出す coder.cstructname coder.inline 使用する MATLAB 構造体用に生成された C 構造体の名前を指定する サブ関数のインライン化を行う MATLAB のサブ 関数内で coder.inline( always ) が使われる場 合 対応するコードが生成された C コード内で インライン化される coder.target coder.nullcopy coder.config 予約された変数で MATLAB インタープリターの実行中は empty になる コード生成時と MATLAB モードとで異なる処理を定義できる if isempty(coder.target) % MATLAB 実行時に使用されるコード else % コード生成時に使われるコード end ゼロ と定義された変数に対する初期化ステートメントの抑止 結果的にコードはやや高速化するが 読み取り前にすべての変数のスライスが書き込まれていることを必ず確認する必要がある コマンドラインで codegen コマンドにより C コードを生成する場合 設定オブジェクトを作成して必要なすべてのオプションを設定する 5