原文地址:matlab与C混合编程
作者:Jaksky
刚开始接到这个任务的时候一筹莫展,matlab和c用得都还不熟呢,混合编程就更糊涂了,于是上网到处搜方法,结果发现由于版本问题以及方法的多样性搞得很混乱,慢慢整理下:
1.1 通过Matlab Engine方式
1.2 直接调用Matlab的C/C++数学函数库
1.3 用Matlab自带的Matlab Compiler
1.4 使用matcom工具
但matcom也有以下不足:
1.5 使用Matlab的Combuilde工具
以上四种方法中第一种很好理解,但由于以matlab为后台运行,所以肯定不能脱离matlab,且运行速度慢。
其他几种方法在matlab后期版本中关系就比较混乱了。
由于matcom公司被matlab所收购,新版本的matlab使用deploytool工具[旧版本为comtool]即可以将所需要的函数文件通 过mcc编译器编译转换成dll文件,而且支持struct,支持函数嵌套,脚本文件没试过,所以就不清楚了。其实也就是调用C/C++动态连接库的方 法。
原来以为使用了deploytool工具后就能把所有函数文件编译成C能识别的格式,从而完全脱离matlab运行,结果不然,如果主机 上安装有matlab,那么需要对路径进行设置,从而使C找到matlab中的matrix.h,mclmrrt.lib等文件,具体后面会提到。如果主 机没有matlab,那么需要一个MCR[matlab compile runtime]提供matlab环境。
我主要使用的就是deploytool工具编程的方法:
1.先要完成Matlab C/C++编译器的设置,在matlab中:
>> mbuild -setup
Please choose your compiler for building standalone MATLAB applications:
Would you like mbuild to locate installed compilers [y]/n? y
Select a compiler:
[1] Lcc-win32 C 2.4.1 in E:PROGRA~1MATLABR2009bsyslcc
[2] Microsoft Visual C++ 6.0 in C:Program FilesMicrosoft Visual Studio
[0] None
Compiler: 2
Please verify your choices:
Compiler: Microsoft Visual C++ 6.0
Location: C:Program FilesMicrosoft Visual Studio
Are these correct [y]/n? y
Trying to update options file: C:UsersjikunAppDataRoaming
From template:
Done . . .
2. 输入deploytool命令,写一个你所需要生成的动态链接文件的名称a[不要与函数名称相重叠],在Target选择C shared library,确定,生成a.prj文件,在弹出的窗口中点击add Files,将你所需要编译转换的matlab函数文件添加进去[支持嵌套函数,struct],注意保证函数文件的正确性,否则后面容易出错。
3.点击build,生成src和distrib两个文件夹,build过程中的信息最好保存为log文件,文件中的Link:......里面有很多.lib,都是C运行程序时所要调用到的静态链接文件,在C文件中需添加进去。
4. 点击package,会自动将需要的文件打包为exe文件,里面包含a.dll,a.h,a.lib,readme.txt,最后运行时只需要这些文件就 可以了,但是为了在工程中能看到编译后的原matlab函数在C中的定义,从而便于编程和调试还需添加src文件夹下的 _component_data.c和a.c。
5.在visual C++中:
若主机已安装matlab,则需添加路径,如下:
tools->options->Directories->platform默认Win32
show directories for中
include files添加##matlab安装路径externinclude
library files添加
具体需要哪些路径取决于需要哪些matlab中的.h,.lib文件
若主机未安装matlab,则需安装MCR - matlab compiler runtime,然后按上述要求添加路径,运行程序。
5.写一个test.c文件,如下开头
#include "matrix.h" //mxArray在此头文件下定义
#include "a.h"
#pragma comment(lib,"a.lib") //动态链接文件
#pragma comment(lib,"mclmcrrt.lib") //matlab编译时Link中出现的动态链接文件。
void main(){
aInitialize(); //初始化,这下面才能调用matlab转成C后的函数
mlfchannel(.......); //所有matlab函数文件都变成了以mlf开头的函数,输入输出均为mxArray *型,注意matlab与C数据存储方式的不同,matlab按列存储,c按行存储,所有的输入输出参数均以指针形式传递
aTerminate();
//若有mxArray型变量,需要释放空间。
}
整个流程大致如此,期间还碰到若matlab函数输入参数可变时如何处理,输入输出为cell型,struct型时如何转换数据等问题,不一一列举了。