C ソース MEX ファイル arrayProduct.c
の作成
この例では、C 行列 APIで定義された MATLAB® 配列を使用して、MATLAB で C 関数 arrayProduct
を呼び出す MEX ファイルを作成する方法を説明します。ソース ファイル全体は、ここで参照できます。
この例を使用するには、以下が必要です。
C または C++ ソース コードを記述する機能。これらのファイルは MATLAB エディターで作成します。
MATLAB でサポートされるコンパイラ。サポートされているコンパイラの最新の一覧については、サポートされるコンパイラ Web サイトを参照してください。
mex
ビルド スクリプト。
独自の C 開発環境を使用する場合は、MEX スクリプト オプションによるカスタム ビルドで詳細を参照してください。
C 関数 arrayProduct
次のコードは、1 行 N 列の行列 y
をスカラー値 x
で乗算し、結果を配列 z
に返す関数 arrayProduct
を定義します。これらの C ステートメントは C++ アプリケーションでも使用できます。
void arrayProduct(double x, double *y, double *z, int n) { int i; for (i=0; i<n; i++) { z[i] = x * y[i]; } }
ソース ファイルの作成
MATLAB エディターを開いてファイルを作成し、次の情報を含む MEX ファイルをドキュメント化します。
/* * arrayProduct.c - example in MATLAB External Interfaces * * Multiplies an input scalar (multiplier) * times a 1xN matrix (inMatrix) * and outputs a 1xN matrix (outMatrix) * * The calling syntax is: * * outMatrix = arrayProduct(multiplier, inMatrix) * * This is a MEX file for MATLAB. */
MATLAB API 関数の宣言を含む C/C++ ヘッダー ファイル mex.h
を追加します。
#include "mex.h"
たとえば c:\work
などの MATLAB パス上にファイルを保存し、arrayProduct.c
という名前を付けます。MEX ファイルの名前は arrayProduct
です。
ゲートウェイ ルーチンの作成
すべての C プログラムには関数 main()
があります。MATLAB は、関数のエントリ ポイントとしてゲートウェイ ルーチン mexFunction
を使用します。以下に示す mexFunction
のコードを追加します。
/* The gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* variable declarations here */ /* code here */ }
次の表では、mexFunction
の入力パラメーターについて説明します。
パラメーター | 説明 |
---|---|
nlhs | 出力 (左辺) 引数の数、つまり配列 plhs のサイズ。 |
plhs | 出力引数の配列。 |
nrhs | 入力 (右辺) 引数の数、つまり配列 prhs のサイズ。 |
prhs | 入力引数の配列。 |
MEX ファイルの入出力パラメーターの確認
nrhs
および nlhs
引数を使用して、MEX ファイルの入出力引数の数を確認します。
入力引数が 2 つ (multiplier
と inMatrix
) であることを確認するには、次のコードを使用します。
if(nrhs != 2) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Two inputs required."); }
次のコードを使用して、出力引数が 1 つ (積 outMatrix
) であることを確認します。
if(nlhs != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "One output required."); }
plhs
および prhs
引数を使用して、引数の型を確認します。このコードでは、prhs[0]
で表される multiplier
がスカラーであることを確認します。
/* make sure the first input argument is scalar */ if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxGetNumberOfElements(prhs[0]) != 1 ) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar", "Input multiplier must be a scalar."); }
このコードでは、prhs[1]
で表される inMatrix
が double
型であることを確認します。
if( !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1])) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble", "Input matrix must be type double."); }
inMatrix
が行ベクトルであることを確認します。
/* check that number of rows in second input argument is 1 */ if(mxGetM(prhs[1]) != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector", "Input must be a row vector."); }
計算ルーチンの作成
arrayProduct
のコードを追加します。この関数は "計算ルーチン" です。計算ルーチンとは、MATLAB で使用する機能を実行するソース コードのことです。
void arrayProduct(double x, double *y, double *z, int n) { int i; for (i=0; i<n; i++) { z[i] = x * y[i]; } }
計算ルーチンはオプションです。このコードは mexFunction
Function ブロックの中に置くこともできます。
プラットフォーム間の柔軟性を高めるためのコードの記述
MATLAB は、プリプロセッサ マクロ mwsize
を提供しています。これは、プラットフォームを基に整数のサイズの値を表します。計算ルーチンでは配列のサイズを int
として宣言しています。この変数 n
と i
の int
宣言を mwsize
に置き換えます。
void arrayProduct(double x, double *y, double *z, mwSize n) { mwSize i; for (i=0; i<n; i++) { z[i] = x * y[i]; } }
計算ルーチンの変数の宣言
次の変数宣言を mexFunction
に入れます。
入力引数の変数を宣言します。
double multiplier; /* input scalar */ double *inMatrix; /* 1xN input matrix */
入力行列のサイズの
ncols
を宣言します。mwSize ncols; /* size of matrix */
出力引数
outMatrix
を宣言します。double *outMatrix; /* output matrix */
後に、mexFunction
の引数をこれらの変数に代入します。
入力データの読み取り
スカラー入力を読み取るには、関数 mxGetScalar
を使用します。
/* get the value of the scalar input */ multiplier = mxGetScalar(prhs[0]);
関数 mxGetDoubles
を使用して、入力行列データを指します。
/* create a pointer to the real data in the input matrix */ inMatrix = mxGetDoubles(prhs[1]);
関数 mxGetN
を使用して、行列のサイズを取得します。
/* get dimensions of the input matrix */ ncols = mxGetN(prhs[1]);
出力データの準備
出力引数 plhs[0]
を作成するには、関数 mxCreateDoubleMatrix
を使用します。
/* create the output matrix */ plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);
関数 mxGetDoubles
を使用して、outMatrix
引数を plhs[0]
に代入します。
/* get a pointer to the real data in the output matrix */ outMatrix = mxGetDoubles(plhs[0]);
計算の実行
引数を arrayProduct
に渡します。
/* call the computational routine */ arrayProduct(multiplier,inMatrix,outMatrix,ncols);
ソース ファイル全体の表示
に存在する matlabroot
/extern/examples/mexarrayProduct.c
とソース ファイルを比較します。エディターでファイル arrayProduct.c
を開きます。
C++ 用の MATLAB データ APIを使用する C++ MEX ファイルの例については、arrayProduct.cpp
を参照してください。この API での MEX ファイル作成の詳細については、C++ MEX 関数を参照してください。
MEX 関数のビルド
MATLAB コマンド プロンプトで、mex
コマンドを使用して関数をビルドします。
mex arrayProduct.c -R2018a
MEX 関数のテスト
s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)
B = 7.5000 10.0000 45.0000
MEX ファイルの入力引数の検証
MEX 関数を呼び出す前に、MATLAB 変数の型を検証することをお勧めします。入力変数 inputArg
をテストし、必要に応じてそれを double
型に変換するには、次のコードを使用します。
s = 5; A = [1.5, 2, 9]; inputArg = int16(A); if ~strcmp(class(inputArg),'double') inputArg = double(inputArg); end B = arrayProduct(s,inputArg)
参考
mex
| mexFunction
| mxCreateDoubleMatrix