週末!プログラミング部

ソフトウェア開発ネタを中心に自分でいろいろ調べた内容を自分の勝手な解釈で思うがままに書いくためのブログ。サンプルソースコード、API、プラットフォーム、プログラミング言語、開発環境などを調査、分析して追求いく予定です。

MATLABからCコードを呼び出してみる

MATLABではコマンドラインからユーザー独自のC/C++プログラムを組み込み関数のように呼び出すことができ、 これらのプログラムはMEX関数と呼ばれているようです。
https://jp.mathworks.com/help/matlab/call-mex-files-1.html

MEX関数はMATLABを高速化させるためによく利用されているようなので使いこなせるようになれば色々と役に立ちそうです。 なので今回はMEX関数というものがどんな感じなのか味見してみようと思います。

やり方は公式サイトの説明を見るのもよいですが以下の方々が書かれた説明のほうがわかりやすかったので参考にさせていただきました。

簡単なMEX関数を作ってみる

以下は、可変引数をもらって、それらの値を合計するMEX関数の例です。
ここではファイル名をtest.cとしてあります。
ファイル名がそのままMEX関数名となります。

#include <mex.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray* prhs[])
{
    int   i = 0;
    double sum = 0;
    
    /* 引数の個数確認 */
    if (nrhs <= 0)
    {
        mexErrMsgTxt("引数がありません。");
    }
    
    /* 返値の個数確認 */
    if (nlhs != 1)
    {
        mexErrMsgTxt("返値がありません。");
    }
    
    /* 引数の個数だけ繰り返し */
    for( i = 0; i < nrhs; i++ )
    {
        /* 引数を加算 */
        sum += (double)mxGetScalar(prhs[i]);
    }
    
    /* 引数を加算して返値にする */
    plhs[0] = mxCreateDoubleScalar(sum);
}

最初におまじないを書いておきます。

#include <mex.h>

続いてMEX関数のインタフェース(MATLABとCの橋渡しをしてくれる関数)としてmexFunctionを定義します。

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray* prhs[])

mexFunctionの引数は以下のとおりです。

  • 第1引数はMATLABへの返値の個数
  • 第2引数はMATLABへの返値配列
  • 第3引数はMATLABからの引数の個数
  • 第2引数はMATLABからの引数配列

この引数を使ってMATLABでやらせたい処理をCで書いていく感じです。

動かしてみる

MATLABコマンドライン上で以下のような感じでコマンドを実行します。
指定した引数で合計がちゃんと計算されていれば成功です!

>> mex test.c
'Microsoft Visual C++ 2019 (C)' でビルドしています。
MEX は正常に完了しました。

>> a = test(3, 2)

a =

     5

>> a = test(3, 2, 1)

a =

     6

>> a = test(3, 2, 1, 99)

a =

   105

>>