Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

coder.extrinsic

外部として関数を宣言し MATLAB で実行する

説明

coder.extrinsic(function)function を外部関数として宣言します。コード ジェネレーターは外部関数の本体のコードを生成せず、代わりに MATLAB® エンジンを使用して呼び出しを実行します。この機能は、実行時に MATLAB エンジンが使用可能な場合にのみ使用できます。MATLAB エンジンが使用可能な状況の例としては、MEX 関数の実行、Simulink® シミュレーション、およびコード生成時 (コンパイル時とも呼ばれる) の関数呼び出しが挙げられます。

スタンドアロン コードの生成中に、コード ジェネレーターは外部関数が呼び出し元の関数に影響を与えるかどうか判断しようとします。外部関数が呼び出し元の関数に影響しない場合 (たとえば、外部関数でプロットを表示する場合)、コード ジェネレーターではコード生成が続行されますが、外部関数は生成されたコードから除外されます。外部関数が呼び出し元の関数に影響を与える場合 (たとえば、外部関数が値を呼び出し元の関数に返す場合)、コード ジェネレーターはコンパイル エラーを出します。

コード生成の範囲外では、MATLAB は coder.extrinsic 命令を無視します。

生成コードでの MATLAB エンジンを使用した関数呼び出しの実行を参照してください。

メモ

外部関数の実行時の出力は、mxArray (別名 MATLAB 配列) です。mxArray に対する有効な操作は、変数に保存すること、別の外部関数に渡すこと、MATLAB に返すことだけです。コードの式で使用するなど、mxArray 値に対して他の操作を実行するには、型が以前の代入によって既に定義されている変数に mxArray を代入することで、mxArray を既知の型に変換する必要があります。mxArrays の利用を参照してください。

coder.extrinsic(function1,...,functionN)function1 から functionN まで外部関数として宣言します。

coder.extrinsic(syn, function1, ... ,functionN) は、外部関数呼び出しの前後における、MATLAB コードと生成された MEX ファイル間のグローバル データの同期を制御します。既定では、コード ジェネレーターは外部関数呼び出しの前後にグローバル変数を同期して、MATLAB コードと MEX 関数間の整合性を最大化します。この既定の動作を変更する方法およびタイミングの詳細については、グローバル データのためのコード生成を参照してください。

すべて折りたたむ

ローカル関数 convertStringToNumber を定義します。この関数は MATLAB 関数str2numの出力を表示します。str2num はコード生成ではサポートされていないため、この関数は MATLAB コードで外部関数として宣言する必要があります。str2num を外部関数として宣言することにより、str2num のコード生成を行わないようコード ジェネレーターに指示します。代わりに、コード ジェネレーターは str2num を実行のために MATLAB に送ります。convertStringToNumber は、コード ジェネレーターで自動的に外部関数として扱われる disp を使用して str2num で返された値を表示します。

type("convertStringToNumber.m")
function convertStringToNumber(c) %#codegen
    coder.extrinsic("str2num");
    disp(str2num(c));
end

convertStringToNumber の MEX コードを生成します。入力を非有界の文字ベクトルに指定します。

codegen convertStringToNumber -args {coder.typeof('c', [1 Inf])} -report
Code generation successful: To view the report, open('codegen/mex/convertStringToNumber/html/report.mldatx')

ファイル convertStringToNumber.c をコード生成レポートから表示できます。このファイルで、MATLAB 関数 disp および str2num に対して C コードが生成されていないことがわかります。その代わりに、生成されたコードでは内部関数 emlrtCallMATLABR2012b を使用して実行するためにこれらの関数を MATLAB に送っています。

文字ベクトルを使用して convertStringToNumber 用に生成された MEX コードを呼び出します。

convertStringToNumber_mex('123')
   123
convertStringToNumber_mex('1,2,3')
     1     2     3
convertStringToNumber_mex(num2str(1:10))
     1     2     3     4     5     6     7     8     9    10

ローカル関数 returnStringToNumber を定義します。この関数は MATLAB 関数str2numの出力を MATLAB に返します。str2num はコード生成ではサポートされていないため、この関数は MATLAB コードで外部関数として宣言する必要があります。str2num を外部関数として宣言することにより、str2num のコード生成を行わないようコード ジェネレーターに指示します。代わりに、コード ジェネレーターは str2num を実行のために MATLAB に送ります。str2num が実行時に返す値は、mxArray (別名 MATLAB 配列) です。mxArray に対する有効な操作は、変数に保存すること、別の外部関数に渡すこと、MATLAB に返すことだけです。mxArrays の利用を参照してください。

type returnStringToNumber.m
function num = returnStringToNumber(c) %#codegen
    coder.extrinsic("str2num");
    num = str2num(c);
end

returnStringToNumber の MEX コードを生成します。入力を非有界の文字ベクトルに指定します。

codegen returnStringToNumber -args {coder.typeof('c', [1 Inf])} -report
Code generation successful: To view the report, open('codegen/mex/returnStringToNumber/html/report.mldatx')

コード生成レポートで、nummxArray であることがわかります。

文字ベクトルを使用して returnStringToNumber 用に生成された MEX コードを呼び出します。

a = returnStringToNumber_mex('123')
a = 123
b = returnStringToNumber_mex('1,2,3')
b = 1×3

     1     2     3

c = returnStringToNumber_mex(num2str(1:10))
c = 1×10

     1     2     3     4     5     6     7     8     9    10

returnStringToNumber_mexmxArray を返しますが、MATLAB は出力を数値ベクトルとして正しく解釈します。

ローカル関数 useStringToNumber を定義します。この関数は MATLAB 関数str2numの出力に基づいて各種メッセージを表示します。str2num はコード生成ではサポートされていないため、この関数は MATLAB コードで外部関数として宣言する必要があります。str2num を外部関数として宣言することにより、str2num のコード生成を行わないようコード ジェネレーターに指示します。代わりに、コード ジェネレーターは str2num を実行のために MATLAB に送ります。str2num が実行時に返す値は、mxArray (別名 MATLAB 配列) です。

mxArray に対する有効な操作は、変数に保存すること、別の外部関数に渡すこと、MATLAB に返すことだけです。コードの式で使用するなど、mxArray 値に対して他の操作を実行するには、型が以前の代入によって既に定義されている変数に mxArray を代入することで、mxArray を既知の型に変換する必要があります。mxArrays の利用を参照してください。

str2numuseStringToNumber で返した mxArray を使用するには、外部関数呼び出しの前に numdouble として初期化します。コンパイル時に、コード ジェネレーターは str2num で返された mxArraydouble に自動的に変換します。この変換されたものを後続の式で使用できます。num を既知の型に設定せずに式で使用した場合、コード生成は失敗します。

type useStringToNumber.m
function useStringToNumber(c) %#codegen
   coder.extrinsic("str2num");
   num = 0;                 % initialize num as a scalar double
   num = str2num(c(1));     % force str2num to return a scalar double
   if num == 1              % because num is a known type, it can be used in expressions
       disp('Starts from one');
   else
       disp('Does not start from one');
   end
end

useStringToNumber の MEX コードを生成します。入力を非有界の character ベクトルに指定します。

codegen useStringToNumber -args {coder.typeof('c', [1 Inf])} -report
Code generation successful: To view the report, open('codegen/mex/useStringToNumber/html/report.mldatx')

コード生成レポートで、str2num の出力が mxArray で、num1 x 1 double であることがわかります。

文字ベクトルを使用して useStringToNumber 用に生成された MEX コードを呼び出します。

useStringToNumber_mex('1,2,3')
Starts from one
useStringToNumber_mex('3,2,1')
Does not start from one

ローカル関数 useStringToNumberVarSize を定義します。この関数は MATLAB 関数str2numの出力に基づいて各種サイズの配列を返します。str2num はコード生成ではサポートされていないため、この関数は MATLAB コードで外部関数として宣言する必要があります。str2num を外部関数として宣言することにより、str2num のコード生成を行わないようコード ジェネレーターに指示します。代わりに、コード ジェネレーターは str2num を実行のために MATLAB に送ります。実行時に str2num から返される値は、mxArray (別名 MATLAB 配列) です。

mxArray に対する有効な操作は、変数に保存すること、別の外部関数に渡すこと、MATLAB に返すことだけです。コードの式で使用するなど、mxArray 値に対して他の操作を実行するには、型が以前の代入によって既に定義されている変数に mxArray を代入することで、mxArray を既知の型に変換する必要があります。mxArrays の利用を参照してください。

str2nummxArray 出力のサイズは実行時に可変であるため、まず num を既知の型 (doubles の空配列) として初期化してから、coder.varsizeを使用して可変サイズとして num を宣言します。num を既知の型に設定せずに使用した場合、コード生成は失敗します。num を可変サイズとして宣言しなかった場合、すべての空でない配列で MEX の実行が失敗します。コード生成のための可変サイズ データの処理の詳細については、可変サイズの配列のコード生成を参照してください。

type useStringToNumberVarSize.m
function num = useStringToNumberVarSize(c) %#codegen
    coder.extrinsic("str2num");
    num = [];                   % initialize num as an empty array of doubles
    coder.varsize("num");       % declare num as variable-sized
    num = str2num(c);           % because num is known to be variable-sized, the generated code does not error when passed a non-empty vector
    if numel(num) > 5           % because num is a known type and not an mxArray, it can be used in expressions
        num = num(1:5);
    end
end

useStringToNumberVarSize の MEX コードを生成します。入力を非有界の文字ベクトルに指定します。

codegen useStringToNumberVarSize -args {coder.typeof('c', [1 Inf])} -report
Code generation successful: To view the report, open('codegen/mex/useStringToNumberVarSize/html/report.mldatx')

コード生成レポートで、str2num の出力が mxArray で、numdoubles の可変サイズの (:? x :?) 配列であることがわかります。

文字ベクトルを使用して useStringToNumberVarSize 用に生成された MEX コードを呼び出します。

a = useStringToNumberVarSize_mex('1,2,3')
a = 1×3

     1     2     3

b = useStringToNumberVarSize_mex(num2str(1:10))
b = 1×5

     1     2     3     4     5

期待どおり、useStringToNumberVarSize_mex から 5 要素数値ベクトルが返されます。

定数値を返す外部関数を呼び出した場合、coder.constを使用してコンパイル時に外部関数を評価するようにコード ジェネレーターに指示できます。そうすると、コード ジェネレーターはこの定数を生成コードで使用します。このコーディング パターンを使用して、外部関数の出力を使用するスタンドアロン コードを生成できます。

ファイル complex.xml 内の複素数を入力引数 theta だけ回転するエントリポイント関数 rotate_complex を定義します。関数 rotate_complex は別のローカル関数 xml2struct を呼び出します。このローカル関数は XML 処理用の MATLAB API を使用してファイル complex.xml 内の XML 形式の数値を構造体に変換します。コード生成では XML 処理用の MATLAB API がサポートされないため、関数 rotate_complex の本文で関数 xml2struct を外部として宣言する必要があります。xml2struct を外部関数として宣言することにより、xml2struct のコード生成を行わないようコード ジェネレーターに指示します。代わりに、コード ジェネレーターは xml2struct を実行のために MATLAB に送ります。ただし、complex.xml はコード生成時と実行時で変更されないため、coder.const を使用して実行時定数として外部関数 xml2struct の出力を扱うようにコード ジェネレーターに指示できます。外部関数ではコード生成時に定数が畳み込まれるため、xml2struct の出力を既知の型に明示的に変換する必要はありません。

サポート ファイル complex.xml を検査します。このファイルには複素数の実数部と虚数部が含まれています。

type complex.xml
<params>
    <param name="real" value="3"/>
    <param name="imaginary" value="4"/>
</params>

関数 xml2struct を定義します。この関数は XML 処理用の MATLAB API を使用して渡された XML ファイルを読み取り、XML パラメーターの名前と値を構造体のフィールドとして保存し、構造体を返します。

type xml2struct.m
function s = xml2struct(file)
s = struct();
import matlab.io.xml.dom.*
doc = parseFile(Parser,file);
els = doc.getElementsByTagName("params");
for i = 0:els.getLength-1
    it = els.item(i);
    ps = it.getElementsByTagName("param");
    for j = 0:ps.getLength-1
        param = ps.item(j);
        paramName = char(param.getAttribute("name"));
        paramValue = char(param.getAttribute("value"));
        paramValue = evalin("base", paramValue);
        s.(paramName) = paramValue;
    end
end

xml2struct を使用して complex.xml を構造体に変換する MATLAB エントリポイント関数 rotate_complex を定義します。次に、関数 rotate_complex が入力引数 theta と等しい角度 (度単位) だけ複素数を回転し、その結果得られた複素数を返します。この関数では、coder.extrinsic 命令を使用して関数 xml2struct を外部として宣言し、coder.const 命令を使用してその出力の定数畳み込みを行います。

type rotate_complex.m
function y = rotate_complex(theta) %#codegen
coder.extrinsic("xml2struct");
s = coder.const(xml2struct("complex.xml"));

comp = s.real + 1i * s.imaginary;
magnitude = abs(comp);
phase = angle(comp) + deg2rad(theta);
y = magnitude * cos(phase) + 1i * sin(phase);

end

codegenコマンドを使用して rotate_complex のスタティック ライブラリを生成します。入力の型を double 型のスカラーに指定します。

codegen -config:lib rotate_complex -args {0} -report 
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because
Embedded Coder is not installed, this might cause some Embedded Coder features
to fail.

Code generation successful (with warnings): To view the report, open('codegen/lib/rotate_complex/html/report.mldatx')

生成された C++ ファイル rotate_complex.c を検査します。関数 xml2struct の出力が生成されたコードでハードコードされることを観察します。

type codegen/lib/rotate_complex/rotate_complex.c
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: rotate_complex.c
 *
 * MATLAB Coder version            : 24.1
 * C/C++ source code generated on  : 25-Jan-2024 15:05:31
 */

/* Include Files */
#include "rotate_complex.h"
#include <math.h>

/* Function Definitions */
/*
 * Arguments    : double theta
 * Return Type  : creal_T
 */
creal_T rotate_complex(double theta)
{
  creal_T y;
  double y_tmp;
  y_tmp = 0.017453292519943295 * theta + 0.92729521800161219;
  y.re = 5.0 * cos(y_tmp);
  y.im = sin(y_tmp);
  return y;
}

/*
 * File trailer for rotate_complex.c
 *
 * [EOF]
 */

入力引数

すべて折りたたむ

外部から呼び出す MATLAB 関数。文字ベクトルとして指定します。

例: coder.extrinsic('patch')

データ型: char

グローバル変数の同期。'-sync:on' または '-sync:off' として指定します。既定では、コード ジェネレーターは各外部関数呼び出しの前後にグローバル変数を同期します。この既定の動作を変更する方法およびタイミングの詳細については、グローバル データのためのコード生成を参照してください。

例: coder.extrinsic('-sync:off','cellfun')

制限

  • coder.extrinsic を使用して外部関数として宣言した関数では、coder.ceval を使用することはできません。

  • コード ジェネレーターが渡したデータを外部関数にコピーしてデータを実行のために MATLAB に送るため、外部関数はパフォーマンスに影響を及ぼすことがあります。逆に、MATLAB は転送用の出力データを MEX 関数環境にコピーして戻します。

  • コード ジェネレーターは、coder.extrinsic を使用したプライベート フォルダー内の関数の呼び出しをサポートしていません。

  • コード ジェネレーターは、coder.extrinsic を使用したローカル関数の呼び出しをサポートしていません。

  • コード生成では、以下に該当するまたは以下が含まれている、外部関数に渡される値、外部関数から返される値はサポートされません。

    • ハンドル クラス

    • 関数ハンドル

    • 不透明な値 (coder.opaqueを参照)

ヒント

  • コード ジェネレーターでは、plotdispfigure など、多くの MATLAB 可視化関数が外部関数として自動的に処理されます。coder.extrinsic を使用してこれらの関数を外部関数として明示的に宣言する必要はありません。

  • 外部関数として宣言しなければならない関数を検出するには、関数 coder.screener を使用します。この関数はコード生成の準備状態ツールを実行します。これにより、MATLAB コード内にコード生成でサポートされない機能や関数がないかどうかが調べられます。コード生成の準備状態ツールを使ったコードのチェックを参照してください。

拡張機能

C/C++ コード生成
MATLAB® Coder™ を使用して C および C++ コードを生成します。

GPU コード生成
GPU Coder™ を使用して NVIDIA® GPU のための CUDA® コードを生成します。

バージョン履歴

R2011a で導入