はじめに
タイトルの通り、MATLABからCコードを呼び出す方法のまとめです。全く仕組みがわからない所から、資料を漁ってようやく理解が深まってきたので、自分の備忘も兼ねつつ、初学者のためになればと記録します。
環境
MATLAB R2020a
MATLAB Support for MinGW-w64 C/C++ Compiler
Visual Studio 2017
Cコードの呼び出し方
Cコードは「MEXファイル」に変換して呼び出すことが可能
MEXファイルとは、Wikipediaによりますと[1]
"A MEX file is a type of computer file that provides an interface between MATLAB or Octave and functions written in C, C++ or Fortran. It stands for "MATLAB executable"."
とのことで、
個人的には、CコードをMEXという実行ファイルのような形式に変換して呼び出すことができる、という理解です。
MEXファイルのビルド方法
MATLABにmex関数が存在するので、これを使ってビルドすると良いようです。
mex filename
ちなみにmexファイルを作成する際に、最初「MATLAB Support for MinGW-w64 C/C++ Compiler」がないとエラーになったので、MATLAB上部の[アドオン]ボタンから追加しました。
MEXファイルのmain関数的なものを用意する必要がある
じゃあ既存のcコードをmexすれば良いのね簡単簡単と思ってたら出鼻をくじかれました。
エラー: mex
LINK : error LNK2001: 外部シンボル "mexFunction" は未解決です。
filename.lib : fatal error LNK1120: 1 件の未解決の外部参照
"mexFunction"が未解決ですとしかられていますが、mexFunctionとは[2]、
C 行列 API で作成された C/C++ MEX 関数へのエントリ ポイント
とのことです。確かにこれがないと機械にはわからないですよね。
mexFunctionの仕組み
@shohiroseさんの[MATLAB] MEX関数の作成方法にて、わかりやすくまとめてくださっていたので、リンクを貼らせて頂きます。勉強になりました、ありがとうございます。
MathWorksの公式ドキュメントにも記載のある通り、そして@shohiroseさんも書いてくださっている通り、
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[])
上記の構文の中で
・nlhs = 戻り値の数
・plhs = 戻り値へのポインタの配列
・nrhs = 引数の数
・prhs = 引数へのポインタの配列
となります。
この仕組みで、引数や戻り値のやりとりをするようです。
mexFunctionを使ったわかりやすい例
とはいえ、、、私はここまで来ても具体的な使い方がわからずはまっていたのですが、良い例に出会えたのでシェアします。
C MEX ファイルでの文字列の受け渡し
上のページからもリンクに飛んで頂けますが、MATLABのコマンドウィンドウで下記を入力し、revord.cを見て頂くと非常にわかりやすいです。
edit([matlabroot '/extern/examples/refbook/revord.c']);
ポイントとしては、
・自作の関数を作成および既存のCコードを転用可能(例の中のrevord関数)
・mexFunctionから自作の関数を呼び出す
・自作の関数の入力・出力は、mexFunctionの引数に紐づける
・紐づけの際はC 行列 APIを使う(MATLAB上の変数を、Cで理解できる形に変換しているという個人的な理解です)
私の環境でも無事にMEXファイルを作成し、Cコードの処理を呼び出すことに成功しました。
>> mex -v revord.c
>> x = 'abcde';
>> y = revord(x)
y =
'edcba'
結論として
既存のCコードは、mexFunctionから呼び出せる形に書き換えて、MEXファイルに変換することで呼び出せます。
補足:MEXファイルはWindows, Linux, Apple Macのいずれにも対応
MathWorksの公式ページにはこんな説明がありました。
Linux® (64 ビット)では
mexa64
Apple Mac (64 ビット)では
mexmaci64
Windows® (64 ビット)では
mexw64
という拡張子で、それぞれMEXファイルが作成されるようです。試していませんが、どのOSでも大丈夫なのだと思います。
参考文献
[1] https://en.wikipedia.org/wiki/MEX_file
[2] https://jp.mathworks.com/help/matlab/apiref/mexfunction.html