matlab与C混合编程

原文地址:matlab与C混合编程 作者:Jaksky


刚开始接到这个任务的时候一筹莫展,matlab和c用得都还不熟呢,混合编程就更糊涂了,于是上网到处搜方法,结果发现由于版本问题以及方法的多样性搞得很混乱,慢慢整理下:


1.1 通过Matlab Engine方式



    Matlab Engine是指一组Matlab提供的接口函数,支持C语言, Matlab Engine采用C/S(客户机/服务器)模式,Matlab作为后台服务器,而C程序作为前台客户机,通过Windows的动态控件与服务器通信,向 Matlab Engine传递命令和数据信息,从Matlab Engine接受数据信息。用户可以在前台应用程序中调用这些接口函数,实现对Matlab Engine的控制。采用这种方法几乎能利用Matlab全部功能,但是需要在机器上安装Matlab软件,而且执行效率低,因此在实际应用中不采用这种 方法,在软件开发中也不可行,这种模式只适合个人使用或做演示。

1.2 直接调用Matlab的C/C++数学函数库



    Matlab中提供了可以供C/C++语言调用的C/C++数学函数库,其中包含了大量用C /C++语言重新编写的Matlab数学函数,这些函数涉及到线形代数、数值分析、傅立叶变换、多项式计算、解微分方程等,并且函数库中提供了大量各种矩 阵操作函数,在VC中可以直接使用这些函数,通过这些函数可以在VC中方便的实现在Matlab中矩阵运算功能。用这种方法可以很灵活的调用Matlab 来编写应用程序,但要求读者对C/C++语言非常熟悉,并且这种模式不能包括所有的Matlab函数,尤其是无法充分使用Matlab提供的详尽的绘图函数。

1.3 用Matlab自带的Matlab Compiler



    Matlab Compiler的作用是将m文件转化成C/C++代码(也就是通常所用的mcc命令),这种源代码需要用C/C++编译器编译连接成独立应用程序,在将 m文件转成独立应用程序的过程中生成的C/C++文件,原则上是可以被其它的C/C++代码调用的,编译器可以通过设置mcc命令的选项,将m文件编译成 动态链接库文件、C/C++文件、可执行文件等一系列文件。到matlab R21.1为止,Matlab Compiler的m程序转换成C/C++代码功能有很多限制:
    ⑴不能转换脚本m文件,只能转换m函数;
    ⑵不能使用matlab对象;
    ⑶不能用input或者eval操作matlab空间变量;
    ⑷不能动态地命名变量,然后用load或者save命令来操作;
    ⑸不能处理具有嵌套调用其他m文件的m文件;
    ⑹不能使用MATLAB内联函数;

1.4 使用matcom工具



    这是第三方控件,很小(8M多),原本属于mathtool公司,后来被Mathworks公司合并了,使用该工具可以将m脚本文件和m函数转化成相同功能的C/C++文件,相比其它方法使用matcom具有如下优点:
    ⑴转换过程简单(由matcom工具自动实现),容易实现;
    ⑵可以方便的生成动态链接库文件(dll)和可执行文件(exe);
    ⑶不仅可以转换独立的脚本文件,也可以转换嵌套脚本文件;
    ⑷设置环境后,可以使用Matlab的工具箱函数;
但matcom也有以下不足:
    ⑴对struct等类的支持有缺陷,对class数据类型;
    ⑵部分绘图语句无法实现或得不到准确图象,尤其是三维图象;
    ⑶当涉及到的复杂函数调用时嵌套的文件数量很多。
    因此在不涉及到三维做图以及m文件不大的情况下推荐使用。

1.5  使用Matlab的Combuilde工具


     COM是component object module的简称,它是一种通用的对象接口,任何语言只要按照这种接口标准,就可以实现调用它。Matlab6.5新推出来的Combuilder就是 把用Matlab编写的程序做成com组件,供其他语言调用。该方法实现简单,通用性强,而且几乎可以使用Matlab的任何函数(注意:不支持脚本文 件,脚本文件使用时要改为函数文件),因此在程序较大、调用工具箱函数或调用函数较多时推荐使用,这也是Matlab公司推荐的使用方法。


  以上四种方法中第一种很好理解,但由于以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:UsersjikunAppDataRoamingMathWorksMATLABR2009bcompopts.bat
From template:              E:PROGRA~1MATLABR2009bbinwin32mbuildoptsmsvc60compp.bat
 
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安装路径externlibwin32microsoft
具体需要哪些路径取决于需要哪些matlab中的.h,.lib文件

若主机未安装matlab,则需安装MCR - matlab compiler runtime,然后按上述要求添加路径,运行程序。

5.写一个test.c文件,如下开头
#include "matrix.h"  //mxArray在此头文件下定义
#include "a.h"          //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型时如何转换数据等问题,不一一列举了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值