副标题#e#
众所周知,MATLAB是一个成果强大的数学软件,擅长于用矩阵运算完成各类数学成果。可是其措施需要在MATLAB情况下表明执行,效率不高。假如能将它强大的函数库用于C语言,操作C来编译执行,MATLAB将能发挥更大的浸染。所以,MATLAB从5.0开始已经提供了与外部C/C++措施的应用措施接口,为操作C语言挪用MATLAB的函数提供了大概。可是MATLAB的接口成长很快,到MATLAB 6.5已经提供了对VC 7.0的支持,同时对C的接口相对付5.X版本有了必然的改变。
在MATLAB傍边,我们操作M文件来实现函数,每一个M文件实现一个单独的成果,这一点和C语言傍边的函数是彼此对应的。所以,假如我们能将MATLAB中的M文件转化为C语言下的一个单个函数,就能实现MATLAB中相应的成果。
实现要领
整个进程可分为三个主要部门,用MATLAB将M文件翻译为C语言文件,从生成的C语言文件提取出有用语句,编写数据转换措施实现参数名目转换。整个进程最终将把M文件翻译成C语言傍边的一个具有沟通成果的函数,供其它的措施挪用。
本文用一个最简朴的M文件来示例:
文件名:messay.m
function c=messay()
a=3.4;
b=5.6;
c=sqrt(a)+sqrt(b);
该m文件实现了计较
1、将M文件编译为C语言文件
为了将M文件翻译为C语言文件,需要举办必然的配置,这里假设编写C语言的情况为VC6.0,在MATLAB呼吁提示符下输入mex -setup和mbuild -setup呼吁,在相应选项中选择Microsoft Visual C/C++即可。
在MATLAB呼吁行中利用mcc呼吁将messay.m翻译为C代码。
mcc -m messay.m
个中的参数-m代表mcc呼吁将把m文件翻译成C语言的代码。
翻译呼吁将在messay.m地址的文件夹下生成三个C语言文件:messay.h,messay.c和messay_main.c。个中messay_main.c提供了main()函数;messay.h提供了整个措施的函数声明;messay.c包括了MATLAB生成的成果函数。这三个文件傍边,messay.c中包括了我们所需要的数学函数。
#p#副标题#e#
2、提取有用语句
通过阐明,发明由mcc生成的代码内部参数传送方法由MATLAB链接库划定,难以窜改,因此需要提取有用的代码,并变动生成代码的参数通报方法。同时从生成代码的注释中可以看出,真正蕴含M文件成果实现的代码段都在Mmessay()函数傍边(该函数名的默认结构方法为前缀M加上M文件的文件名),而其它的生成函数仅实现参数通报和尺度化接口处事的成果。
所以提代替码的详细要领是操作messay.c傍边生成的static mxArray * Mmessay(int nargout_)函数,对该函数举办修改,而其他的生成函数都可以忽略不消。原生成的Mmessay()代码如下:
static mxArray * Mmessay(int nargout_) {
mexLocalFunctionTable save_local_function_table = mclSetCurrentLocalFunctionTable(&_local_function_table_messay);
mxArray * c = NULL;
mxArray * b = NULL;
mxArray * a = NULL;
mlfAssign(&a, _mxarray0_);
mlfAssign(&b, _mxarray1_);
mlfAssign(&c, mclPlus(mlfSqrt(mclVv(a, "a")), mlfSqrt(mclVv(b, "b"))));
mclValidateOutput(c, 1, nargout_, "c", "messay");
mxDestroyArray(a);
mxDestroyArray(b);
mclSetCurrentLocalFunctionTable(save_local_function_table_);
return c;
}
在生成代码傍边,mclSetCurrentLocalFunctionTable和mclSetCurrentLocalFunctionTable函数为两个外部函数,将参数传给外部,与其相关的部门都对C措施利用数学函数没有影响。最终实际有用并执行运算的只有一句:
mlfAssign(&c, mclPlus(mlfSqrt(mclVv(a, "a")), mlfSqrt(mclVv(b, "b"))));
实际上,由MATLAB翻译的C语句中,大部门的和实际计较有关的语句和自生成的函数都以mlf开头,所以寻找有用语句的简朴要领就是直接寻找mlf为前缀的代码。
3、参数名目转换
该当指出,MATLAB所有的计较都是基于一种名为mxArray的数据布局之上的,所有的浮点数、向量可能是矩阵在MATLAB傍边都是通过mxArray布局来举办存储和通报的。虽然,MATLAB所提供的所有数学函数也都是基于这样一种数据布局举办运算的。所以,要利用MATLAB的生成代码,就必需将C语言傍边常用的浮点数和整数转换为mxArray布局。
本例中操作MATLAB函数mxArray *mlfScalar(double v)和函数double *mxGetPr(mxArray *)来实现参数名目转换。函数mlfScalar()将double型变量存入一个新建的mxArray布局中,并返回指针,而函数mxGetPr()将mxArray布局生存的实数的实部取出。至于其它参数转换要领可参看参考文献3中的相关部门。
最终可以编写这样一个操作了MATLAB数学函数并实现计较的函数:
#p#分页标题#e#
double Mmessay(double ina, double inb) {
mxArray *a,*b,*c; //三个用于MATLAB数学函数计较的参数
double *outc; //计较功效变量
a=mlfScalar((double)ina); //操作mlfScalar()举办范例转换
b=mlfScalar((double)inb);
mlfAssign(&c, mclPlus(mlfSqrt(mclVv(a, "a")), mlfSqrt(mclVv(b, "b"))));
outc=mxGetPr(c); //c得到功效的实部,即功效
mxDestroyArray(a); //释放空间
mxDestroyArray(b);
mxDestroyArray(c);
return *outc;
}
到此,整个翻译进程完成,可是还不能直接挪用。在这个函数傍边运用到了MATLAB的数学库函数mlfSqrt()、mlcPlus()和数据转换函数mlfScalar()、mxGetPr()。由于这些函数是固化在链接库傍边的,为了毗连执行,必需插手几个库文件和几个静态链接库lib文件。所需要的库文件为mcc呼吁生成的messay.c文件傍边所插手的库文件,一般为libmatlb.h,而需要插手的静态链接库文件如下:
libmat.lib,libmatlb.lib,libmex.lib,libmx.lib
假如没有以上文件,可以用VC的lib呼吁将MATLAB相应的def文件转化为lib文件,转化名目为lib /def:filename.def /machine:ix86 /out:filename.lib。
要领的范围
利用本文所用的要领可以将M文件翻译为C语言的函数,可是要受到两个因素的制约。
1、成果的实现受到MATLAB C函数库的限制
这种翻译的机制是由MATLAB提供的,mcc呼吁能直接翻译的函数也仅范围于MATLAB原有的函数。因为这些函数已经被MATLAB6.5编译好,一般以mlf为前缀,存于动态链接库傍边并可被C语言直接挪用。这些函数在参考文献4中可以查到。而超出了这个范畴的函数,并在M文件傍边被嵌套利用,在用mcc举办翻译的时候,mcc将在函数名前加上前缀mlf,并进一步翻译该函数。
可是,这种翻译受到MATLAB参数通报的限制,而不能直接挪用,在编译时会呈现找不到相应的外部函数的错误。办理步伐是手动将所有被翻译的函数举办参数通报方法的调解。假如M文件傍边包括的函数被嵌套翻译的层数很深,这样的事情量是庞大并且不行接管的。
同时许多东西箱傍边界说的函数也是不能利用这种要领举办翻译的。MATLAB的东西箱更新速度很快,而相应的MATLAB C的函数库有必然滞后,导致许多最新的东西箱傍边的函数是不能被翻译的。
2、翻译自己存在的限制
因为这种翻译是遵守C语言要求的,因而对付内存分派要求和C语言差异的函数和一些关于图形显示范例的函数(包罗大量的GUI相关函数)也不能被正确的翻译。譬喻mash.m和step.m这两个较常用的MATLAB函数,由于上述的限制,就不能用本要领举办翻译。
对付上述的问题,可以操作在C措施傍边运用MATLAB引擎的要领动态挪用MATLAB的库函数,根基上可以办理上述所有的函数不能被正确翻译和图形显示的问题。可是,运用MATLAB引擎的要领需要操作ActiveX的自动化处事器,在运行的时候措施会在靠山执行一个MATLAB的线程而不能完全离开MATLAB的情况,也就意味着在纯C的情况下是不能运用的,必需要先安装MATLAB并可以或许在运行时支持多线程事情。详细的要领可以参阅参考文献3。
MATLAB 5.X和MATLAB 6.5的区别
对付本要领有以下几点区别需要留意:
(1)措施傍边所需的库文件由5.X版本的matrix.h、mcc.h、matlab.h改为mex.h、libmatlb.h、libmatlbm.h等库文件。
(2)措施所需要插手的静态链接库文件由5.X需要的libmmfile.lib、libmatlb.lib、libmcc.lib、libmx.lib改为libmat.lib、libmatlb.lib、libmex.lib、libmx.lib四个文件。
(3)API函数窜改许多,固然数学函数库即mlf前缀的函数少有窜改,可是关于变量成立,内存打点和数据范例转换的函数产生改变,即许多原mcc前缀的函数改为用mx为前缀的函数取代,使得许多5.X翻译的C措施代码不能在6.5相应的库下运行通过。
(4)6.5版本中直接增加了在VC情况下对M文件的支持。在执行mbuild -setup的设置呼吁后,MATLAB在VC中提供了MATLAB Project Wizard,可在VC情况下直接成立MATLAB的工程来翻译M文件。可是这种翻译要领在碰着未界说函数嵌套时将错误的把函数名翻译为变量名,而mcc呼吁将进一步翻译内部嵌套的函数。