Main Content

C ソース MEX ファイル arrayProduct.c の作成

この例では、C 行列 APIで定義された MATLAB® 配列を使用して、MATLAB で C 関数 arrayProduct を呼び出す MEX ファイルを作成する方法を説明します。ソース ファイル全体は、ここで参照できます。

この例を使用するには、以下が必要です。

  • C または C++ ソース コードを記述する機能。これらのファイルは MATLAB エディターで作成します。

  • MATLAB でサポートされるコンパイラ。サポートされているコンパイラの最新の一覧については、サポートされるコンパイラ Web サイトを参照してください。

  • C 行列 APIおよび C MEX API の関数。

  • 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 つ (multiplierinMatrix) であることを確認するには、次のコードを使用します。

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] で表される inMatrixdouble 型であることを確認します。

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 として宣言しています。この変数 niint 宣言を 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/mex に存在する arrayProduct.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)

参考

| |

関連するトピック