最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。
MATLAB® コードで関数 foo
の呼び出しを処理すると、コード ジェネレーターは、foo
の定義を見つけ、その本文のコードを生成します。場合によっては、コード生成をバイパスし、代わりに MATLAB エンジンを使用して呼び出しを実行できます。coder.extrinsic('foo')
を使用して、foo
の呼び出しでコードを生成するのではなく、MATLAB エンジンを実行に使用することを宣言します。このコンテキストで、foo
は外部関数として参照されます。この機能は、MATLAB エンジンが MEX 関数で使用できる場合、またはコンパイル時に coder.const
を呼び出しているときにのみ使用できます。
foo
を呼び出して coder.extrinsic('foo')
を含める関数のスタンドアロン コードを生成すると、コード ジェネレーターで foo
が出力に影響するかどうか判断されます。foo
が出力に影響しない場合、コード ジェネレーターではコード生成が続行されますが、foo
は生成されたコードから除外されます。影響する場合、コンパイル エラーが発生します。
コード ジェネレーターでは、plot
、disp
、figure
など、多くの MATLAB 可視化関数が外部関数として自動的に処理されます。coder.extrinsic
を使用してそれらを外部関数として明示的に宣言する必要はありません。たとえば、MATLAB 環境で結果を可視化するために、plot
を呼び出す場合があります。plot
を呼び出す関数から MEX 関数を生成した後、生成した MEX 関数を実行すると、コード ジェネレーターは、関数 plot
の呼び出しを MATLAB エンジンに送信します。ライブラリまたは実行可能ファイルを生成する場合、生成コードには関数 plot
への呼び出しが含まれません。コード生成レポートでは MATLAB コードから外部関数への呼び出しを強調表示することで、どの関数が MATLAB 環境でのみサポートされているかが容易にわかるようになっています。
一般的な可視化関数以外のサポートされていない関数は、外部関数として宣言しなければなりません (コード生成における関数呼び出しの解決を参照してください)。外部関数はコンパイルされず、代わりにシミュレーション中に MATLAB 内で実行されます (シミュレーション時の外部関数の解決を参照してください)。
関数を外部関数として宣言するには、以下の 2 つの方法があります。
coder.extrinsic
コンストラクトを main 関数またはローカル関数内で使用する (MATLAB 関数の外部関数としての宣言を参照)。
feval
を使用した関数の間接的な呼び出し (feval を使用した MATLAB 関数の呼び出しを参照)。
MATLAB 関数を外部関数として宣言するには、coder.extrinsic
コンストラクトを main 関数またはローカル関数の先頭に追加します。
coder.extrinsic('function_name_1', ... , 'function_name_n');
以下のコードは、MATLAB 関数 patch
をローカル関数 create_plot
内で外部関数として宣言しています。axis
はコード ジェネレーターで自動的に外部のものとして扱われる一般的な可視化関数の 1 つなので、axis
を外部として宣言する必要はありません。
function c = pythagoras(a,b,color) %#codegen % Calculates the hypotenuse of a right triangle % and displays the triangle. c = sqrt(a^2 + b^2); create_plot(a, b, color); function create_plot(a, b, color) %Declare patch as extrinsic coder.extrinsic('patch'); x = [0;a;a]; y = [0;0;b]; patch(x, y, color); axis('equal');
コード ジェネレーターは、patch
と axis
のコードを生成せず、代わりに実行のためにこれらを MATLAB に送り込みます。
関数をテストするには以下の手順に従います。
次のコマンドを MATLAB プロンプトで実行し、pythagoras
を MEX 関数に変換します。
codegen -report pythagoras -args {1, 1, [.3 .3 .3]}
コード生成レポートへのリンクをクリックし、レポートで create_plot
の MATLAB コードを表示します。
レポートでは関数 patch
および axis
が強調表示され、MATLAB 環境でのみサポートされていることが示されます。
次のコマンドを実行することでこの MEX 関数を実行します。
pythagoras_mex(3, 4, [1.0 0.0 0.0]);
MATLAB が、直角三角形のプロットを赤い patch オブジェクトとしてプロットします。
以下の処理を行う場合に coder.extrinsic
コンストラクトを使用します。
不要なコード生成を行わず、シミュレーション中に何も出力しない MATLAB 関数を呼び出す (シミュレーション時の外部関数の解決を参照してください)。
コードに説明コメントを付けて、デバッグしやすいようにする。ソース コードをスキャンして coder.extrinsic
ステートメントを検出し、mxArrays
を作成して伝播させる可能性がある MATLAB 関数への呼び出しを隔離することができます (mxArrays の利用を参照してください)。
タイピングの手間が省けます。1 つの coder.extrinsic
ステートメントを使えば、後に続く関数呼び出しは、呼び出しとステートメントが同じスコープ内にある限り、外部呼び出しになります (外部関数宣言のスコープを参照してください)。
呼び出し関数のスコープ範囲内ではすべての MATLAB 関数を外部関数として宣言します (外部関数宣言のスコープを参照してください)。スコープを絞り込むには、feval
を使います (feval を使用した MATLAB 関数の呼び出しを参照してください)。
コードを生成する場合、外部関数の宣言に際して以下のルールを守ってください。
関数を呼び出す前に外部関数として宣言する。
条件ステートメントでは外部宣言を使用しない。
coder.extrinsic
コンストラクトは、関数のスコープをもっています。たとえば、以下のコードについて考えます。
function y = foo %#codegen coder.extrinsic('rat','min'); [N D] = rat(pi); y = 0; y = min(N, D);
この例では、rat
と min
が、メイン関数 foo
で呼ばれるときは毎回外部関数として処理されます。メイン関数内の外部宣言のスコープを絞り込むには、以下の 2 つの方法があります。
この例のように、ローカル関数内で MATLAB 関数を外部関数として宣言します。
function y = foo %#codegen coder.extrinsic('rat'); [N D] = rat(pi); y = 0; y = mymin(N, D); function y = mymin(a,b) coder.extrinsic('min'); y = min(a,b);
ここでは、関数 rat
はメイン関数 foo
内で呼び出されるときは毎回外部関数ですが、関数 min
は、ローカル関数 mymin
内で呼び出されるときにのみ外部関数です。
feval を使用した MATLAB 関数の呼び出しに説明されているように feval
を使って MATLAB 関数を呼び出します。
関数 feval
は、コード生成時に自動的に外部関数として解釈されます。したがって、コンパイルしてコードを生成するよりも、feval
を使って MATLAB 環境で実行する関数を呼び出す方が便利です。
次の例を考えます。
function y = foo coder.extrinsic('rat'); [N D] = rat(pi); y = 0; y = feval('min', N, D);
feval
は外部関数であるため、ステートメント feval('min',
N, D)
は MATLAB によってコンパイルされるのではなく、評価されます。これは、この 1 回の呼び出しだけのために関数 min
を外部関数として宣言するのと同じ結果になります。それに対して、関数 rat
は、関数 foo
内で常に外部関数のままです。
コード ジェネレーターは feval
を使用したローカル関数またはプライベート フォルダー内にある関数の呼び出しをサポートしません。
非静的メソッド foo
をもつクラス myClass
を宣言し、このクラスのインスタンス obj
を作成するとします。メソッド obj.foo
を、コード生成に使用する MATLAB コードの外部メソッドとして宣言する場合は、以下のルールに従います。
foo
の呼び出しを関数呼び出しとして記述する。ドット表記を使用して呼び出しを記述しない。
構文 coder.extrinsic('foo')
を使用して foo
を外部関数として宣言する。
たとえば、myClass
を次のように定義します。
classdef myClass properties prop = 1 end methods function y = foo(obj,x) y = obj.prop + x; end end end
foo
を外部関数として定義する MATLAB 関数の例を以下に示します。
function y = myFunction(x) %#codegen coder.extrinsic('foo'); obj = myClass; y = foo(obj,x); end
非静的メソッドは通常のメソッドとも呼ばれます。メソッドと関数を参照してください。
コード ジェネレーターは外部関数 (コード生成をサポートしていない関数) への呼び出しを次のように解決します。
シミュレーション中、コード ジェネレーターは外部関数への呼び出しに対してコードを生成しますが、関数の内部コードは生成しません。したがって、シミュレーションは MATLAB ソフトウェアをインストールしたプラットフォーム上でしか実行できません。
コード生成中、コード ジェネレーターは、たとえば、mxArrays
を出力変数に返すことによる影響など、外部関数を呼び出している関数の出力にその外部関数が影響を与えるかどうか判断しようとします (mxArrays の利用を参照してください)。出力に変化がない場合、コード生成は続行されますが、外部関数は生成されたコードから除外されます。それ以外の場合、コード ジェネレーターはコンパイラ エラーを発行します。
外部関数の出力は、mxArray
(別名 MATLAB 配列) です。mxArrays
に対する有効な操作は以下のみです。
mxArrays
を変数に格納する
mxArrays
を関数に渡す、関数から返す
mxArrays
を実行時に既知の型に変換する
他の操作で外部関数から返された mxArrays
を使用するには、mxArrays の既知の型への変換に説明されているように、まず既知の型に変換しなければなりません。
mxArray
を既知の型に変換するには、mxArray
を型が定義されている変数に割り当てます。実行時に、mxArray
は割り当てられた変数の型に変換されます。ただし、mxArray
のデータがその変数の型と一致していない場合はランタイム エラーが発生します。
たとえば、以下のコードについて考えます。
function y = foo %#codegen coder.extrinsic('rat'); [N D] = rat(pi); y = min(N, D);
ここでは、最上位の関数 foo
が外部の MATLAB 関数 rat
を呼び出し、この関数が、pi
の有理分数近似の分子 N
と分母 D
を表す 2 つの mxArrays
を返します。この mxArrays
を別の MATLAB 関数に渡すことはできますが (この場合は min
) 、min
が返す mxArray
を出力 y
に代入することはできません。
この関数 foo
を Simulink® モデルの MATLAB Function ブロックで実行すると、コードはシミュレーション中に次のエラーを発生します。
Function output 'y' cannot be of MATLAB type.
この問題を修正するには、以下に示すように、y
を、min
が返すと想定される値の型とサイズ (この場合、スカラーで double) に定義します。
function y = foo %#codegen coder.extrinsic('rat'); [N D] = rat(pi); y = 0; % Define y as a scalar of type double y = min(N,D);
コード生成時には、MATLAB の実行時環境が完全にサポートされているわけではありません。したがって、MATLAB 関数を外部呼び出しする場合には以下の制限事項が適用されます。
呼び出し元の検査や、呼び出し元のワークスペースに読み書きを行う MATLAB 関数は、コード生成時は機能しません。そのような関数は以下のとおりです。
MATLAB デバッガーは、外部関数で定義されている変数を検査できません。
生成コード内の関数は、実行時に外部関数が以下のアクションを行う場合、予測できない結果を生じる場合があります。
フォルダーの変更
MATLAB パスの変更
MATLAB ファイルの削除または追加
警告の状態の変更
MATLAB の基本設定の変更
Simulink のパラメーターの変更
コード ジェネレーターは、coder.extrinsic
を使用したプライベート フォルダー内の関数の呼び出しをサポートしていません。
コード ジェネレーターは、coder.extrinsic
を使用したローカル関数の呼び出しをサポートしていません。
関数の呼び出しは、入力が最大 64 個、出力が最大 64 個まで対応します。