コマンド ラインでの C コードの生成
このチュートリアルでは、MATLAB® Coder™ codegen コマンドを使用して、MATLAB 関数の静的な C ライブラリを生成します。最初に、固定の既定サイズの入力のみを受け入れる C コードを生成します。その後、複数の異なるサイズの入力を受け入れる C コードを生成します。
コードは MATLAB Coder アプリを使用して生成することもできます。このワークフローのチュートリアルについては、MATLAB Coder アプリを使用した C コードの生成を参照してください。
MATLAB Coder では、スクリプトではなく MATLAB 関数からコードが生成されます。MATLAB コードがスクリプトの形式の場合は、コードを生成する前にスクリプトのラッパー関数を作成します。
チュートリアル ファイル: ユークリッド距離
この例を開いて、このチュートリアルのファイルを取得します。
チュートリアル ファイルの説明
このチュートリアルで使用するファイルは、euclidean_data.mat、euclidean.m、euclidean_test.m、build_lib_fixed.m、および build_lib_variable.m です。
MATLAB データ ファイル
euclidean_data.matには、3 次元ユークリッド空間の単一の点と 3 次元ユークリッド空間の他の複数の点の 2 つのデータが格納されています。具体的には次のとおりです。xは、3 次元ユークリッド空間の点を表す3行1列の列ベクトルです。cbは、3行216列の配列です。cbの各列が 3 次元ユークリッド空間の点を表します。
MATLAB ファイル
euclidean.mには、この例の "コア アルゴリズム" を実装する関数euclideanが含まれています。この関数はxとcbを入力として受け取ります。xとcbの各点の間のユークリッド距離を計算して次の量を返します。列ベクトル
y_min。xに最も近い点を表すcbの列と等しくなります。列ベクトル
y_max。xから最も遠い点を表すcbの列と等しくなります。2 次元のベクトル
idx。ベクトルy_minとy_maxのcbにおける列インデックスが格納されます。2 次元のベクトル
distance。xとの間の計算された最短距離と最長距離が格納されます。
function [y_min,y_max,idx,distance] = euclidean(x,cb) % Initialize minimum distance as distance to first element of cb % Initialize maximum distance as distance to first element of cb idx(1)=1; idx(2)=1; distance(1)=norm(x-cb(:,1)); distance(2)=norm(x-cb(:,1)); % Find the vector in cb with minimum distance to x % Find the vector in cb with maximum distance to x for index=2:size(cb,2) d=norm(x-cb(:,index)); if d < distance(1) distance(1)=d; idx(1)=index; end if d > distance(2) distance(2)=d; idx(2)=index; end end % Output the minimum and maximum distance vectors y_min=cb(:,idx(1)); y_max=cb(:,idx(2)); end
MATLAB スクリプト
euclidean_test.mは、データ ファイルeuclidean_data.matをワークスペースに読み込みます。その後、関数euclideanを呼び出してy_min、y_max、idx、およびdistanceを計算します。このスクリプトで計算された量がコマンド ラインに表示されます。euclidean_data.matの読み込みは、コア アルゴリズムを呼び出す前に実行される事前処理のステップです。結果の表示は事後処理のステップとなります。% Load test data load euclidean_data.mat % Determine closest and farthest points and corresponding distances [y_min,y_max,idx,distance] = euclidean(x,cb); % Display output for the closest point disp('Coordinates of the closest point are: '); disp(num2str(y_min')); disp(['Index of the closest point is ', num2str(idx(1))]); disp(['Distance to the closest point is ', num2str(distance(1))]); disp(newline); % Display output for the farthest point disp('Coordinates of the farthest point are: '); disp(num2str(y_max')); disp(['Index of the farthest point is ', num2str(idx(2))]); disp(['Distance to the farthest point is ', num2str(distance(2))]);
ビルド スクリプト
build_lib_fixed.mとbuild_lib_variable.mには、MATLAB コードから静的な C ライブラリを生成するためのコマンドが固定サイズの入力を受け入れるものと可変サイズの入力を受け入れるものに分けて格納されています。これらのスクリプトの内容については、このチュートリアルの後半で C コードを生成するときに説明します。
ヒント
テスト スクリプトを使用して、コア アルゴリズムを実装する関数から事前処理と事後処理のステップを分割します。こうすることで、アルゴリズムを簡単に再利用できます。ここでは、コア アルゴリズムを実装する MATLAB 関数のコードを生成します。テスト スクリプトのコードは生成しません。
MATLAB 関数の C コードの生成
元の MATLAB コードの実行
MATLAB でテスト スクリプト euclidean_test.m を実行します。y、idx、および distance が出力に表示されます。
Coordinates of the closest point are: 0.8 0.8 0.4 Index of the closest point is 171 Distance to the closest point is 0.080374 Coordinates of the farthest point are: 0 0 1 Index of the farthest point is 6 Distance to the farthest point is 1.2923
MATLAB コードをコード生成に適したものにする
MATLAB コードをコード生成に適したものにするには、コード アナライザーとコード生成の準備状態ツールを使用します。MATLAB エディターのコード アナライザーは、コードの入力時にそれを常にチェックします。コード アナライザーは、コードの問題を報告し、パフォーマンスと保守性を最大化するための修正方法を提案します。コード生成の準備状態ツールでは、MATLAB コード内にコード生成でサポートされない機能や関数がないかどうかを調べることができます。
C/C++ コード生成でサポートされる MATLAB の一部の組み込み関数とツールボックス関数、クラス、および System object には、特定のコード生成の制限があります。それらの制限と関連する使用上の注意事項については、該当するリファレンス ページの拡張機能のセクションに記載されています。詳細については、C/C++ コードの生成でサポートされている関数およびオブジェクトを参照してください。
MATLAB エディターで、
euclidean.mを開きます。MATLAB エディターの右上隅にあるコード アナライザー メッセージ インジケーターは緑色になります。アナライザーは、コード内にエラー、警告または改善すべき点を検出しませんでした。関数宣言の後に、
%#codegen命令を追加します。function [y,idx,distance] = euclidean(x,cb) %#codegen
%#codegen命令により、コード生成に固有の警告やエラーがコード アナライザーで特定されます。コード アナライザー メッセージ インジケーターが赤色になり、コード生成の問題が検出されたことが示されます。

警告メッセージを表示するには、下線が引かれているコード部分にカーソルを移動します。この警告は、コードを生成するには、変数
idxとdistanceを完全に定義してから添字を付けなければならないことを示しています。これらの警告が発生するのは、コード ジェネレーターが変数のサイズをコードにおける最初の出現箇所で決定するためです。この問題を修正するには、関数onesを使用して、それらの配列の割り当てと初期化を同時に行います。% Initialize minimum distance as distance to first element of cb % Initialize maximum distance as distance to first element of cb idx = ones(1,2); distance = ones(1,2)*norm(x-cb(:,1));
コード アナライザー メッセージ インジケーターが再び緑色になり、コード生成に関する問題がほかに検出されていないことが示されます。

コード アナライザーの使用の詳細については、コード アナライザーを使用したエラーと警告についてのコードのチェックを参照してください。
ファイルを保存します。
コード生成の準備状態ツールを実行するには、MATLAB コマンド ラインから関数
coder.screenerを呼び出します。coder.screener('euclidean')euclideanについては、ツールでコード生成に関する問題は検出されません。詳細については、コード生成の準備状態ツールを参照してください。メモ
コード アナライザーとコード生成の準備状態ツールで、コード生成に関するすべての問題を検出できるわけではありません。これらのツールで検出されたエラーや警告を解決したら、MATLAB Coder を使用してコードを生成し、MATLAB コードに準拠違反の問題がほかにないかどうかを調べてください。
これで、codegen コマンドを使用してコードをコンパイルする準備ができました。"コンパイル" とは、ここでは MATLAB コードから C/C++ コードを生成することを指しています。
メモ
MATLAB コードのコンパイルとは、MATLAB コードから C/C++ コードを生成することを指します。他のコンテキストでは、コンパイルという用語が C/C++ コンパイラのアクションを指す場合もあります。
入力の型の定義
C では静的型付けが使用されるため、コード ジェネレーターは MATLAB ファイル内のすべての変数のクラス、サイズ、実数/複素数をコード生成時 ("コンパイル時") に判別しなければなりません。したがって、ファイルのコードを生成するときに、エントリポイント関数に対するすべての入力引数のプロパティを指定しなければなりません。"エントリポイント関数" は、コードを生成する最上位の MATLAB 関数です。
codegen コマンドを使用してコードを生成する場合は、-args オプションを使用してエントリポイント関数に対するサンプル入力パラメーターを指定します。コード ジェネレーターは、この情報を使用して入力引数のプロパティを決定します。
次のステップでは、codegen コマンドを使用して、エントリポイント関数 euclidean から MEX ファイルを生成します。
実行時の問題の確認
エントリポイント関数から MEX 関数を生成します。MEX 関数は MATLAB 内から呼び出すことができる生成コードです。MEX 関数を実行し、生成された MEX 関数と元の MATLAB 関数が同じように機能するかどうかを確認します。
生成された C コードでの診断が難しいランタイム エラーを検出して修正することができるため、このステップを実行することをお勧めします。既定では、MEX 関数にはメモリ整合性チェックが含まれます。このチェックにより、配列の範囲と次元のチェックが実行されます。このチェックを実行することにより、MATLAB 関数に対して生成されたコード内のメモリ整合性の違反が検出されます。詳細は、実行時チェックの制御を参照してください。
MATLAB コードを効率良く動作する C/C++ ソース コードに変換するためにコード ジェネレーターによって行われる最適化により、特定の状況において、元のソース コードと生成後のコードで異なる動作になることがあります。生成されたコードと MATLAB コードの相違点を参照してください。
codegenコマンドを使用してeuclidean.mの MEX ファイルを生成します。MEX 関数を検証するには、MATLAB 関数euclideanの呼び出しを生成された MEX 関数の呼び出しに置き換えてテスト スクリプトeuclidean_testを実行します。% Load the test data load euclidean_data.mat % Generate code for euclidean.m with codegen. Use the test data as example input. codegen euclidean.m -args {x,cb} -test euclidean_test
既定で、
codegenは、現在のフォルダーにeuclidean_mexという名前の MEX 関数を生成します。-argsオプションを使用して、エントリポイント関数euclideanに対するサンプル入力パラメーターを指定します。コード ジェネレーターは、この情報を使用して入力引数のプロパティを決定します。-testオプションを使用して、テスト ファイルeuclidean_test.mを実行します。このオプションにより、テスト ファイルのeuclideanの呼び出しがeuclidean_mexの呼び出しに置き換えられます。
出力は、次のようになります。
この出力が元の MATLAB 関数で生成された出力と一致することから、MEX 関数を確認できます。これで、Running test file: 'euclidean_test' with MEX function 'euclidean_mex'. Coordinates of the closest point are: 0.8 0.8 0.4 Index of the closest point is 171 Distance to the closest point is 0.080374 Coordinates of the farthest point are: 0 0 1 Index of the farthest point is 6 Distance to the farthest point is 1.2923
euclideanのスタンドアロンの C コードを生成する準備ができました。
メモ
MATLAB コードからスタンドアロン C/C++ コードを生成する前に、MEX 関数を生成します。生成された MEX 関数を実行して、実行時の動作が MATLAB 関数と同じであることを確認します。生成された MEX 関数の応答が MATLAB とは異なる場合、またはエラーが発生する場合は、スタンドアロン コード生成に進む前にこれらの問題を解決しなければなりません。そうしないと、生成するスタンドアロン コードの信頼性が低くなり、未定義の動作が発生する可能性があります。
C コードの生成
ビルド スクリプト build_lib_fixed.m に euclidean.m のコードの生成に使用するコマンドが含まれています。
% Load the test data load euclidean_data.mat % Generate code for euclidean.m with codegen. Use the test data as example input. codegen -report -config:lib euclidean.m -args {x, cb}
codegenは、ファイルeuclidean.mを読み取り、MATLAB コードを C コードに変換します。-reportオプションはcodegenに対して、コード生成の問題をデバッグしたり MATLAB コードがコード生成に適していることを確認したりするために使用できるコード生成レポートを生成するよう指示します。-config:libオプションはcodegenに対して、既定の MEX 関数を生成するのではなく静的な C ライブラリを生成するよう指示します。-argsオプションはcodegenに対して、サンプル入力パラメーターxとcbのクラス、サイズ、実数/複素数を使用してeuclidean.mのコードを生成するよう指示します。
codegen コマンドで適切なオプションを使用することで、C スタティック ライブラリを生成する代わりに、MEX 関数や他の C/C++ ビルド タイプを生成するように選択することもできます。各種のコード生成オプションの詳細については、codegen を参照してください。
ビルド スクリプトを実行します。
MATLAB はビルド ファイルを処理し、メッセージを出力します。
コード ジェネレーターにより、スタンドアロンの C スタティック ライブラリCode generation successful: View report.euclideanがに生成されます。ここで、work\codegen\lib\euclideanはチュートリアル ファイルが含まれているフォルダーです。workレポート ビューアーでコード生成レポートを表示するには、[レポートの表示] をクリックします。
コード生成中にコード ジェネレーターでエラーや警告が検出された場合は、レポートに問題の説明と問題がある MATLAB コードへのリンクが表示されます。コード生成レポートを参照してください。
ヒント
コマンド ラインでのコードの生成にはビルド スクリプトを使用します。ビルド スクリプトでは、コマンド ラインで繰り返し実行する一連の MATLAB コマンドを自動化できるため、時間の節約となり、入力エラーをなくすことができます。
生成された C コードと元の MATLAB コードとの比較
生成された C コードと元の MATLAB コードを比較するには、C ファイル euclidean.c と euclidean.m ファイルを MATLAB エディターで開きます。
生成された C コードに関する重要な情報を次に示します。
関数シグネチャは次のようになります。
void euclidean(const double x[3], const double cb[648], double y_min[3], double y_max[3], double idx[2], double distance[2])const double x[3]は MATLAB コード内の入力xに対応します。xのサイズは3で、これは MATLAB コードのコードを生成したときに使用したサンプル入力の合計サイズ (3 行 1 列) に対応します。const double cb[648]は MATLAB コード内の入力cbに対応します。cbのサイズは648で、これは MATLAB コードをコンパイルしたときに使用したサンプル入力の合計サイズ (3 行 216 列) に対応します。この例の生成されたコードでは、1 次元配列を使用して MATLAB コードの 2 次元配列を表します。生成されたコードには、4 つの追加の入力引数があります。配列
y_min、y_max、idx、およびdistanceです。これらの配列は出力値を返すために使用されます。これらは、元の MATLAB コードの出力引数y_min、y_max、idx、およびdistanceに対応します。コード ジェネレーターでは関数名とコメントが保持されます。変数名については、可能であればコード ジェネレーターで保持されます。
メモ
MATLAB コード内の変数が定数値に設定された場合、生成された C コード内では変数としては表れません。生成された C コード内では、変数の実際の値が含まれています。
Embedded Coder® では、MATLAB コードと生成された C/C++ コードを対話形式でトレースできます。Interactively Trace Between MATLAB Code and Generated C/C++ Code (Embedded Coder)を参照してください。
可変サイズ入力の C コードの生成
生成した euclidean.m の C 関数は、コード生成時に指定したサンプル入力と同じサイズの入力のみを受け入れます。ただし、対応する MATLAB 関数への入力配列は任意のサイズにすることができます。チュートリアルのこのパートでは、可変サイズの入力を受け入れる C コードを euclidean.m から生成します。
ここでは、生成される C コードの x と cb の次元について、プロパティを次のように設定するとします。
xとcbの両方の最初の次元を最大サイズ3の可変にします。xの 2 番目の次元を値1の固定にします。cbの 2 番目の次元を最大サイズ216の可変にします。
これらの入力プロパティを指定するには、関数 coder.typeof を使用します。coder.typeof(A,B,1) は、クラスと実数/複素数が A と同じで、上限がサイズ ベクトル B の対応する要素で与えられる可変サイズの入力を指定します。coder.typeof を使用するビルド スクリプト build_lib_variable.m を使用して、生成される C ライブラリの可変サイズ入力のプロパティを指定します。
% Load the test data load euclidean_data.mat % Use coder.typeof to specify variable-size inputs eg_x=coder.typeof(x,[3 1],1); eg_cb=coder.typeof(cb,[3 216],1); % Generate code for euclidean.m using coder.typeof to specify % upper bounds for the example inputs codegen -report -config:lib euclidean.m -args {eg_x,eg_cb}
次に、前と同じ手順でコードを生成できます。euclidean.c の生成された C コードの関数シグネチャは次のようになります。
void euclidean(const double x_data[], const int x_size[1], const double cb_data[],
const int cb_size[2], double y_min_data[], int y_min_size[1],
double y_max_data[], int y_max_size[1], double idx[2], double
distance[2])x_data、cb_data、y_min_data、および y_max_data は、元の MATLAB 関数の入力引数 x と cb および出力引数 y_min と y_max に対応します。これで、x_data、cb_data、y_min_data、および y_max_data のサイズを実行時に指定する 4 つの追加の入力引数 x_size、cb_size、y_min_size、および y_max_size を C 関数が受け入れるようになります。