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