ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

MATLAB 関数の呼び出し

コード生成ソフトウェアは、C コード生成でサポートされていない場合でも、関数のコード生成を試みます。また、plotdispfigure などの多くの一般的な可視化関数の呼び出しを検出します。このような関数は外部関数と同様に扱われますが、coder.extrinsic を使用して、extrinsic であると宣言する必要はありません。シミュレーション中、コード生成ソフトウェアはこのような関数に対してコードを生成しますが、関数の内部コードは生成しません。スタンドアロン コードの生成中に、MATLAB® は可視化関数が呼び出し元の関数の出力に影響を与えるかどうか判断しようとします。出力に変化がない場合、MATLAB はコード生成を進めますが、生成コードからは可視化関数を除外します。そうしなければ、コンパイルエラーが発生します。

たとえば、MATLAB 環境で結果を可視化するために、plot を呼び出す場合があります。plot を呼び出す関数から MEX 関数を生成し、生成した MEX 関数を実行すると、コード生成ソフトウェアは、plot 関数への呼び出しを MATLAB に送信します。ライブラリまたは実行可能ファイルを生成する場合、生成コードには plot 関数への呼び出しが含まれません。コード生成レポートでは MATLAB コードから外部関数への呼び出しを強調表示することで、どの関数が MATLAB 環境でのみサポートされているかが容易にわかるようになっています。

一般的な可視化関数以外のサポートされていない関数は、(pause など) 外部関数として宣言しなければなりません (コード生成における関数呼び出しの解決を参照してください)。外部関数はコンパイルされず、代わりにシミュレーション中に MATLAB 内で実行されます (シミュレーション時の MATLAB による外部関数の解決方法を参照してください)。

関数を外部関数として宣言するには、以下の 2 つの方法があります。

MATLAB 関数の外部関数としての宣言

MATLAB 関数を外部関数として宣言するには、coder.extrinsic コンストラクトをメイン関数またはローカル関数の先頭に追加します。

coder.extrinsic('function_name_1', ... , 'function_name_n');

外部関数の宣言

以下のコードは、MATLAB patch 関数をローカル関数 create_plot 内で外部関数として宣言しています。

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 and axis as extrinsic

coder.extrinsic('patch'); 

x = [0;a;a];
y = [0;0;b];
patch(x, y, color);
axis('equal');

コード生成ソフトは、axis がコード生成でサポートされていないことを検出し、自動的に外部関数として扱います。コンパイラは、patchaxis のコードを生成せず、代わりに実行のために MATLAB に送り込みます。

関数をテストするには以下の手順に従います。

  1. 次のコマンドを MATLAB プロンプトで実行し、pythagoras を MEX 関数に変換します。

    codegen -report pythagoras -args {1, 1, [.3 .3 .3]}

  2. コード生成レポートへのリンクをクリックし、レポートで create_plot の MATLAB コードを表示します。

    レポートでは関数 patch および axis が強調表示され、MATLAB 環境でのみサポートされていることが示されます。

  3. 次のコマンドを実行することでこの MEX 関数を実行します。

    pythagoras_mex(3, 4, [1.0 0.0 0.0]);

    MATLAB が、直角三角形のプロットを赤い patch オブジェクトとしてプロットします。

coder.extrinsic コンストラクトを使用する場面

以下の処理を行う場合に coder.extrinsic コンストラクトを使用します。

  • 不要なコード生成を行わず、シミュレーション中に何も出力しない MATLAB 関数 (pause など) を呼び出す (シミュレーション時の 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);

この例では、ratmin が、メイン関数 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 を使用した 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 内で常に外部関数のままです。

シミュレーション時の MATLAB による外部関数の解決方法

MATLAB は外部関数 (コード生成をサポートしていない関数) への呼び出しを次のように解決します。

シミュレーション中、MATLAB は 外部関数への呼び出しに対してコードを生成しますが、関数の内部コードは生成しません。したがって、シミュレーションは MATLAB ソフトウェアをインストールしたプラットフォーム上でしか実行できません。

コード生成中、MATLAB は内部で外部関数を呼び出している関数の出力が、その外部関数に影響を受けるかを判断しようとします。たとえば、外部関数が mxArrays を出力変数に返すことによって与えられる影響です (mxArrays の利用を参照してください)。出力に変化がない場合、MATLAB はコード生成を進めますが、生成コードからは外部関数を除外します。それ以外の場合、MATLAB はコンパイラ エラーを発行します。

mxArrays の利用

外部関数の出力は、mxArray (別名 MATLAB 配列) です。mxArrays に対する有効な操作は以下のみです。

  • 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 のパラメーターの変更

関数の引数に対する制限事項

関数の呼び出しは、入力が最大 64 個、出力が最大 64 個まで対応します。

この情報は役に立ちましたか?