MATLAB エンジンを使用した固定小数点アルゴリズムの高速化時における関数呼び出しの実行
MATLAB® コードで関数 foo の呼び出しを処理すると、コード ジェネレーターは、foo の定義を見つけ、その本文のコードを生成します。場合によっては、コード生成をバイパスし、代わりに MATLAB エンジンを使用して呼び出しを実行できます。coder.extrinsic('foo') を使用して、foo の呼び出しでコードを生成するのではなく、MATLAB エンジンを実行に使用することを宣言します。このコンテキストで、foo は外部関数として参照されます。この機能は、実行時に MATLAB エンジンが使用可能な場合にのみ使用できます。このような状況の例としては、MEX 関数の実行、Simulink® シミュレーション、またはコード生成時 ("コンパイル時" とも呼ばれる) の関数呼び出しが挙げられます。
foo を呼び出して coder.extrinsic('foo') を含める関数のスタンドアロン コードを生成すると、コード ジェネレーターで foo が出力に影響するかどうか判断されます。foo が出力に影響しない場合、コード ジェネレーターではコード生成が続行されますが、foo は生成されたコードから除外されます。影響する場合、コンパイル エラーが発生します。
特定の MATLAB 関数内に coder.extrinsic('foo') 命令を含めると、その MATLAB 関数内での foo の呼び出しはすべて外部関数として宣言されます。または、外部宣言のスコープを foo の 1 回の呼び出しのみに絞り込むことができます。feval を使用した MATLAB 関数の呼び出し (MATLAB Coder)を参照してください。

関数を外部関数として宣言する場合
次のような場合は、MATLAB 関数を外部関数として宣言することを検討してください。
関数が表示アクションまたはログ アクションを実行する場合。このような関数は主にシミュレーション中に役立ち、組み込みのシステムでは使用されません。
MEX の実行または Simulink のシミュレーションで、コード生成についてサポートされない MATLAB 関数を使用する場合。このワークフローは、非シミュレーション ターゲットには適用されません。
coder.constを使用して関数呼び出しを定数畳み込みするようコード ジェネレーターに指示する場合。このような場合、MATLAB エンジンで呼び出しが実行できるコード生成中にのみ関数が呼び出されます。
coder.extrinsic 構成要素の使用
関数 foo を外部関数として宣言するには、MATLAB コードに次のステートメントを含めます。
coder.extrinsic('foo')関数をコード生成の外部関数として宣言する場合は、以下のルールを守ってください。
関数を呼び出す前に外部関数として宣言する。
条件ステートメントでは外部宣言を使用しない。
外部関数の戻り値を既知の型に代入する。mxArrays の利用 (MATLAB Coder)を参照してください。
追加情報と例については、coder.extrinsic を参照してください。
コード ジェネレーターでは、plot、disp、figure など、多くの MATLAB 可視化関数が外部関数として自動的に処理されます。coder.extrinsic を使用してそれらを外部関数として明示的に宣言する必要はありません。たとえば、MATLAB 環境で結果を可視化するために、plot を呼び出す場合があります。plot を呼び出す関数から MEX 関数を生成した後、生成した MEX 関数を実行すると、コード ジェネレーターは、関数 plot の呼び出しを MATLAB エンジンに送信します。ライブラリまたは実行可能ファイルを生成する場合、生成コードには関数 plot への呼び出しが含まれません。
MATLAB Coder™ を使用して MEX またはスタンドアロン C/C++ コードを生成すると、コード生成レポートでは MATLAB コードから外部関数への呼び出しが強調表示されます。レポートを調べることで、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内で呼び出されるときにのみ外部関数です。coder.extrinsic構造を使用する代わりに、fevalを使用して MATLAB 関数を呼び出します。このアプローチについては、次の節で説明します。
非静的メソッドの外部宣言
非静的メソッド 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
非静的メソッドは通常のメソッドとも呼ばれます。メソッドの構文を参照してください。
追加の用途
以下の処理を行う場合に coder.extrinsic 構成要素を使用します。
不要なコード生成を行わず、シミュレーション中に何も出力しない MATLAB 関数を呼び出す。
コードに説明コメントを付けて、デバッグしやすいようにする。ソース コードをスキャンして
coder.extrinsicステートメントを検出し、mxArraysを作成して伝播させる可能性がある MATLAB 関数への呼び出しを隔離することができます。mxArrays の利用 (MATLAB Coder)を参照してください。
feval を使用した MATLAB 関数の呼び出し
外部宣言のスコープを 1 つの関数呼び出しのみに絞り込むには、関数 feval を使用します。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 を使用したローカル関数または private フォルダー内にある関数の呼び出しをサポートしません。
mxArrays の利用
外部関数の実行時の出力は、mxArray (別名 MATLAB 配列) です。mxArrays に対する有効な操作は以下のみです。
mxArrayを変数に保存する。mxArrayを外部関数に渡す。関数から MATLAB に
mxArrayを返す。mxArrayを実行時に既知の型に変換する。前の代入によって型が既に定義されている変数にmxArrayを代入します。次の例を参照してください。
他の操作 (たとえば、MATLAB Function ブロックから Simulink 実行に返すなど) で外部関数から返された mxArray を使用するには、最初にそれを既知の型に変換しなければなりません。
関数の入力引数が 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 に渡される入力は mxArrays であるため、コード ジェネレーターは自動的に min を外部関数として扱います。その結果、min は mxArray を返します。
MATLAB Coder を使用して MEX 関数を生成する場合、MEX 関数はその出力を MATLAB に返すため、min で返されたこの mxArray を出力 y に直接代入できます。
codegen fooCode generation successful.
ただし、foo を Simulink モデルの MATLAB Function ブロックに含め、モデルを更新または実行すると、次のエラーが発生します。
コード生成では、このコンテキストにおけるこの関数からの mxArray 出力はサポートされません。既知の型を使用して出力変数 'y' を初期化してください。
このエラーは、mxArray を Simulink に返すことができないために発生します。この問題を修正するには、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);
この例では、外部関数 min の出力が、コードを生成しているエントリポイント関数 foo の出力 y に影響を与えます。foo のスタンドアロン コード (スタティック ライブラリなど) を生成しようとすると、コード ジェネレーターでは、外部関数呼び出しを無視できず、コード生成エラーが発生します。
codegen -config:lib foo
外部関数 'min' の出力が呼び出し元の関数に影響を与えている可能性があるため、スタンドアロン コードを生成できません。'min' への呼び出しを取り除くか、その出力が使用されないことを確認してください。
外部関数の使用に関する制限
コード生成時には、MATLAB の実行時環境が完全にサポートされているわけではありません。したがって、MATLAB 関数を外部呼び出しする場合には以下の制限事項が適用されます。
呼び出し元の検査や、呼び出し元のワークスペースに読み書きを行う一部の MATLAB 関数はコード生成でサポートされていません。そのような関数は以下のとおりです。
生成コード内の関数は、実行時に外部関数が以下のアクションを行う場合、予測できない結果を生じる場合があります。
フォルダーの変更
MATLAB パスの変更
MATLAB ファイルの削除または追加
警告の状態の変更
MATLAB の基本設定の変更
Simulink パラメーターの変更
コード ジェネレーターは、
coder.extrinsicを使用した private フォルダー内の関数の呼び出しをサポートしていません。コード ジェネレーターは、
coder.extrinsicを使用したローカル関数または入れ子関数の呼び出しをサポートしていません。コード生成では、外部関数に渡される値または外部関数から返される値で、以下が含まれている値はサポートされません。
ハンドル クラス
関数ハンドル
不透明な値 (
coder.opaque(MATLAB Coder)を参照)
外部関数の呼び出しは、入力が最大 64 個、出力が最大 64 個まで対応します。