贵州高端网站建设,做网站编写,软件开发者平台有哪些,织梦网站程序模板MATLAB 到 C 语言程序的转换可以由两种途径完成#xff0c;其一是 MATLAB 自己提供的 C 语言翻译程序 mcc, 另一种是原第 3 方公司 MathTools 开发的 MATCOM。后者出现较早#xff0c;功能远比 MATLAB 自己的翻译程序强大#xff0c;所以 MathTools 公司已经被 MathWorks 公… MATLAB 到 C 语言程序的转换可以由两种途径完成其一是 MATLAB 自己提供的 C 语言翻译程序 mcc, 另一种是原第 3 方公司 MathTools 开发的 MATCOM。后者出现较早功能远比 MATLAB 自己的翻译程序强大所以 MathTools 公司已经被 MathWorks 公司收购并已将其开发技术融于新推出的 MATLAB 6.0 (Release 12) 中。 依本人的观点二者都不完善有大量的 MATLAB 函数及数据类型是不能兼容变换的所以有时会发现将简洁的 MATLAB 程序翻译成 C 语言程序很晦涩。翻译后的 C 程序几乎不适合手动去维护更谈不上升级了。 有几个不兼容的地方是不能令人容忍的例如 eval() 函数在 C 翻译下是不兼容的最新的 MATLAB 6 才刚刚敢说已经部分兼容了但离真正的兼容还有很长的路要走有很多艰难的技术困难需要克服短时间内不可能有突破性的进展。另一个大的问题是众所周 知MATLAB 新的控制系统工具箱中定义了大量的 LTI 类MATLAB 5 开始也允许使用类与对象的概念这已经向“面向对象”的编程走了一大步但 MATLAB 到 C 的翻译明显都不支持“对象”的数据类型所以在控制系统分析与设计 (当然还有其他的领域) 中这样的转换几乎没有什么实际意义所以不要将这样的转换太理想化。 从转换的程序速度来看因为 mcc 和 MATCOM 都沿用了 MATLAB 的程序运算机制所以不可能大幅度地提高程序运行速度。相反地如果将 MATLAB 程序中明显的瓶颈部分用 C 语言按照 MEX 格式编写则可以大大加快速度。作者在《科学运算语言 MATLAB 5.3 程序设计及应用》一书中以例子做过探讨MCC 可以比快 50%, 而 MEX 的形式可能快上百倍。 〖举例〗分形问题从初始点(x0,y0) 出发按下面的公式生成新的点 (x1,y1) 其 中 gi 为 (0,1) 区间均匀分布的随机数。要求从 (x1,y1) 再生成 (x2,y2),...直至生成 1,000,000 个点(有点夸张但太少了用 MATLAB 测时间不准)。可以下载用 MATLAB 的 M-函数写的程序、用 Mex_C 写的程序。程序调用语句为 N1000000; vrand(N,1); tic; [x,y]frac_tree(0,0,v,N); toc 然后测试一下速度再想法用 MATCOM 或 MCC 转换一下再试试速度。问题MATCOM 程序到底比 M 函数快多少我用 Mex_C 实现的速度可是快100多倍啊下面有文章介绍用 MATCOMVC 能平均快1.5倍 (在别的应用上)依作者的观点为了这区区 1.5 倍还不至于自己给自己找麻烦去用 MATCOM。 这样看可能 MATLAB 到 C 转换唯一的好处就是它能开发具有自主版权的软件了。 所以本人一般不太赞同用这样的转换方法去开发程序尤其不赞成刻意追求 MATLAB C 的方式。本人认为除非必要一般别采用这样的方法。提出这样的观点欢迎商榷。 MATCOM 目前有 BC 和 VC 两个程序MATLAB VC 之家中收录了一些文章。作者见到有下载区有这样的软件。 在这里给出一个下载区的链接 CBuilder 调用 Matlab 的实现方法 国防科技大学机电工程与仪器系 张云洲 摘要本文简要叙述了Matlab语言的优点介绍了在用Borland CBuilder语言开发的Windows应用程序中调用matlab语言实现科学计算和图形绘制的方法。 关键词CBuilder Matlab调用 混合编程 1. 引言 Matlab 是一个高度集成的系统集科学计算、图象处理、声音处理于一体具有极高的编程效率。近年来Matlab已经从最初的“矩阵实验室”渗透到科学与工程 计算的多个领域在自动控制、信号处理、神经网络、模糊逻辑、小波分析等多个方向都有着广泛的应用。 Borland CBuilder是一种新颖的可视化编程语言。在工程应用中我们一般用CBuilder语言编写应用程序实现交互界面、数据采集和端口操作 等但CBuilder在数值处理分析和算法工具等方面其效率远远低于Matlab语言。在准确方便地绘制数据图形方面Matlab语言更具有无 可比拟的优势。此外Matlab还提供功能强大的工具箱。但Matlab的缺点是不能实现端口操作和实时控制。因此若能将两者结合运用实现优势互 补将获得极大的效益。 本文结合实际介绍了应用Borland CBuilder3.0开发的Windos应用程序中对Matlab的调用方法。 2. CBuilder调用Matlab的实现方案 2.1 实现思路 在高版本的Maltab中如Matlab V4.2提供了DDE接口用户可以通过Windows的DDE通讯基制实现外部调用。这种实现方式比较简单但将增大主程序代码影响运行速度。 在Windows系统中DLL是一种很特别的可执行文件可以被多个Windows应用程序同时访问具有固定的共享数据段。该数据段的数据在DLL被 Windows下载前会一直保留在内存中因此可以通过DLL实现用户程序与Matlab之间的数据传输和函数调用。 具体地说 就是利用Matlab的32位动态连接库DLL生成相应的可以被CBuilder调用的DLL用来提供二者之间的基本支撑环境。只需在用户程 序中加载该DLL即可实现其数据段的共享。然后在用户程序中操作DLL数据段的数据并通过某种方式在用户程序中使Matlab执行该DLL就可实现 用户程序对Matlab的调用。其形式可以是混合编程或函数调用非常方便而高效。 2.2 实现方式 Matlab提供了可外部连接的DLL文件通过将其转换为相应的Lib文件并加以必要的设置就可以在CBuilder中直接进行Matlab函数调用实现C Builder语言与Matlab语言的混合编程。 2.2.1 运行环境要求 由于Matlab提供的是32位的DLL。其运行环境要求是Matlab V4.2或更高版本。CBuilder可以进行32位编程这里我们采用的是V3.0版本。 2.2.2 CBuilder下LIB文件的生成 Matlab提供的Def文件允许用户通过Implib命令生成相应的Lib文件。其命令格式为 Implib ???.lib ???.def 在 matlab \extern\include目录下提供了如下三个.Def文件 _libeng.def_libmat.def_libmx.def 通过上述命令可以生成相应的三个Lib文件。这些Lib文件中包含了可外部调用的Matlab函数的必要信息。 3. CBuilder调用Matlab实现计算和绘图 为清楚起见作者通过一个简单的CBuilder例程进行说明。该实例通过调用Matlab实现矩阵运算并绘制图形来演示CBuilder对 Matlab的调用。在CBuilder编辑环境中建立一个新的窗体MyForm并放置一个按钮Demo。将工程文件命名为Try.prj其主 函数为try.cpp。在主函数中我们将使用一个实现Matlab调用的子函数DemoMatlab作为按钮Demo的响应事件。其源代码如下 i nclude vcl.h #pragma hdrstop i nclude Unit1.h #pragma package(smart_init) #pragma resource *.dfm TMyForm *MyForm; __fastcall TMyForm::TMyForm(TComponent* Owner) : TForm(Owner) { } void __fastcall TMyForm::DemoClick(TObject *Sender) { DemoMatlab(); //演示Matlab语言调用 } ---- 为了调用Matlab中的函数必须进行必要的设置将包含这些函数的文件加入工程文件Try.prj。以下是操作过程 a 在头文件中加入Engine.h。其包含了启动Matlab调用和关闭的函数声明。 b 打开Project|Option…对话框点击Directories/Conditionals 在Include Path中加入目录路径 matlab \extern\include该路径包含了engine.h和matlab.h等有用的头文件。 在Library Path中加入 matlab \bin和 matlab \extern\include。这两个目录路径包含了可外部调用的DLL和LIB文件。 c. 点选Project|Add to Project…对话框加入如下库文件 _libeng.lib_libmat.lib和_libmx.lib。 在进行了这些必要的设置之后我们就可以选用适当的函数来实现目标。 以下是子函数DemoMatlab的程序代码。 void DemoMatlab { Engine *eng; //定义Matlab引擎 char buffer[200]; //定义数据缓冲区 int array[6]{1,2,3,4,5,6}; mxArray *S NULL, *T NULL; engOpen(NULL); //打开MATLAB 引擎 ---① S mxCreateDoubleMatrix(1,6, mxREAL); // 产生矩阵变量 mxSetName(S, S); memcpy((char *) mxGetPr(S), (char *) array, 6*sizeof(int)); engPutArray(eng, S); //将变量X置入Matlab的工作空间 engEvalString(eng, T S/S.^2;); //计算 engEvalString(eng, plot(S, T);); //绘制图形 …… …… engOutputBuffer(eng, buffer, 200); //获取Matlab输出 T engGetArray(eng, T); //获得计算结果----② engClose(eng); //关闭Matlab引擎结束调用 mxDestroyArray(S); //释放变量 mxDestroyArray(T); } 若还需要执行其它功能和任务那么按照上面介绍的方法进行变量声明后在①、②处加写需要的语句既可。 当然使用这种方法调用Matlab不能脱离Matlab环境的支撑。但当我们不需要看到Matlab的命令窗口时可将其赋予Swhide属性而加以隐藏。 4. 结语 按照本文介绍的方法来实现CBuilder下应用程序对Matlab的调用可以充分利用Matlab强大的科学计算功能和丰富的工具箱而且具有混 合编程、方便高效的优点。这是C语言和其它高级语言所无法比拟的。按照本文的方法我们还可以编写程序来最充分地利用Matlab的其它资源开发满 足自己需要的程序更有效地完成我们的工作。 VC 下如何利用 Matlab 工具箱进行数字信号处理 潘 卫 明 赵 敏 张 进 芳 (南京航空航天大学 测试工程系 210016) 摘要本文详述了在Vc环境下如何利用Matlab工具箱进行数字信号处理全文以Matlab工具箱中功率谱密度分析函数为例介绍了通过Matlab自带的引擎、Matlab自身的编译器以及利用MathTools公司的Matcom进行对工具箱函数的调用。 关键词Matlab M-文件 引擎 编译器 Matcom Vc Matlab 的信号处理工具箱是信号算法文件的集合它处理的基本对象是信号与系统信号处理工具箱位于目录、Toolbox\Signal下利用工具箱中的文件可 以实现信号的变换、滤波、谱估计、滤波器设计等。在其它的环境如Vc下如果能调用Matlab工具箱中的文件会大大地加快一些算法的实现同时其可靠性 也很高。 利用Matlab引擎 Matlab引擎采用客户和服务器计算方式在运用中Vc的C语言或C语言的程序 作为前端客户机它向Matlab引擎传递命令和数据信息并从Matlab引擎接收数据信息它提供了下列几个函数 engOpen, engGetArray, engPutArray, engEvaString, engOutputBuffer ,engClose与客户机进行交互。 下面例程是在Vc下建一个基于对话框的应用程序在对话框中设置一个Button控件OnMatlabEngine.,在对话框 .cpp文件中加入”engine.h” 和“math.h” 头文件下面给出部分程序清单。 Void CtestmatlabDlg::OnMatlabEngine(){ Engine *ep; mxArray* TNULL,*resultNULL,*mFsNULL,*mnfft NULL; double datax[1024]; char buffer[1024]; for(int j0;j1024;j)//注如通过采集卡采集数据可将采集的数据放在datax[]数组中,此循环就不需要 { double samt(double)(1.0/1024); datax[j]sin(2.0*63.0*samt*3.14159261.15*3.1415926); } double *pPxx,*pFxx; if(!(epengOpen( \0))){//打开Matlab引擎建立与本地Matlab的连接 fprintf(stderr,\n Cant start MATLAB engine\n); exit(-1); } double Fs[1]{1024};//因为Matlab所有参与运算的参数都是矩阵的形式因而下列几行将参数转变 double nfft[1]{1024};//成Matlab可接受的矩阵形式。 TmxCreateDoubleMatrix(1,1024,mxREAL); mnfftmxCreateDoubleMatrix(1,1,mxREAL); mFsmxCreateDoubleMatrix(1,1,mxREAL); mxSetName(T,T); mxSetName(mnfft,mnfft); mxSetName(mFs,mFs); memcpy((char*)mxGetPr(T),(char*)datax, 1024*sizeof(double)); memcpy((char*)mxGetPr(mnfft),(char*)nfft, sizeof(double)); memcpy((char*)mxGetPr(mFs),(char*)Fs,1*sizeof(double)); engPutArray(ep,T); //将转化的参数放入引擎中此时可在Matlab command窗口下查看此参数 engPutArray(ep,mnfft); engPutArray(ep,mFs); engEvalString(ep,[pxx,fo]psd(T,mnfft,mFs);); //利用引擎执行工具箱中文件 engOutputBuffer(ep,buffer,512); //如只想看显示图形可将返回参数去掉psd无返回参数缺省情况下会自动画图形 resultengGetArray(ep,pxx);//取出引擎中的数据放在所指的区域中供后续处理 pPxxmxGetPr(result); resultengGetArray(ep,fo); pFxxmxGetPr(result); engEvalString(ep,plot(fo,10*log10(pxx)););//利用引擎画图 engEvalString(ep,title(功率谱分析);); engEvalString(ep,xlabel(Hz);); engEvalString(ep,ylable(db);); mxDestroyArray(T); //释放内存 mxDestroyArray(mFs); mxDestroyArray(mnfft); mxDestroyArray(result); engEvalString(ep,close;); engClose(ep); } 上述程序在Vc下编译需要将 libeng.dll和libmx.dll两个动态库利用以下的命令 lib/def: 自己的Matlab的安装路径,下同e:\ Matlab\extern\include\*.def /machine:ix86 /out:*.lib来生成程序所需的静态连接库libeng.lib和libmx.lib,将libeng.lib和libmx.lib所在的目录加入 Vc project/link/object/library modules下即可。 利用Matlab自身的编译器调用工具箱中的函数 Matlab 的编译器可将Matlab的M文件转换为为C或C的源代码以产生完全脱离Matlab运行环境的独立的运用程序但Matlab本身的资料说明编译器 如用来建立独立的运用程序不能调用Matlab工具箱中的函数这非常不利于搞一些特殊的算法。本人研究了一段时间发现工具箱中的函数既然是M文件就 一定可以用编译器来编译以提供如Vc的调用函数但是编译器只能编译一个独立的M文件即这个 M文件不依赖于其他的M文件。如果M文件中又调用了其他的M文件可将被调用的M文件拷贝到调用M文件的相应位置作适当的改动就可以用于编译器编译。编 译器不支持图形函数所以M文件中如有图形函数需注释掉。 当Matlab的编译器mcc加入适当的参数-e(mcc –e *.*)或-p(mcc –p *.*)就可生成将输入的M文件转换为适用于特定运用的C或C源代码。这样如果要在Vc下编译通过,还需连入以下几个库libmmfile.dll, libmatlb.dll, libmcc.dll, libmat.dll. libmx.dll. mibut.dll 以及Matlab C MATH库建议采用前述的方法将动态连接改为静态连接。对于C/C编译环境的设置在Matlab command窗口下运行mex –setup 然后依提示操作而对于C/C连接环境的设置运行mbuild –setup依提示操作即可。 下面给出利用编译器将Matlab工具箱中psd.m文件生成可供Vc调用的函数。 将psd.m 文件拷贝一份至Matlab\bin目录下改写相应调用的M文件如nargchk.m, hanning.m等。为生成的代码简洁对于采集数据处理输入参数很明了的情况下可作大量的删减最终使psd.m成为一个不依赖于其他M文件的独立的 M文件注意千万注释掉作图代码最终改成如下形式限于篇幅给出关键的几步 function [Pxx,f]psd(Fs,nfft,noverlap,x) windowo,5*(1-cos(2*pi*(1:nfft)’/(nffft1)));//hanning 窗 dflag’none’; windowwindow(;) …………………………………. 以上只要稍懂Matlab语言和信号处理知识就可完成这项工作。 假设上述代码重新存为testwin.m,在Matlab command 窗口下设置好环境参数运行mcc –e testwin,则可在Matlab\bin下生成testwin.c ,如运行mcc –p testwin 则生成testwin.cpp. Vc下建立一个基于对话框的文件然后在对话框里加一个Button控件OnButtonPsd 将上述生成的.c文件的头文件加入到工程的.cpp中且将#ifdef_cplusplus extern “c”{ #end if c代码声明加入Vc的包含文件和生成的.C的包含文件之间 将#ifdef_cplusplus } #end if加入.cpp文件未尾 为了简洁且便于处理将生成的c函数稍改动给出部分代码如下 void CTestpsdwinDlg::OnButtonPsd(){ mxArray* x_rhs_;//指向采集数据存放区 Fs23510;//数据采集的频率 nfft1024;//1024点的fft double datax[1024]//采集的数据 x_rhs_mxCreateDoubleMatrix(1,1024,mxReal); memcpy(mxGetPr(x_rhs_),datax,1024*sizeof(double)); noverlap512; ………………. ………………. mccCopy(Pxx,Spec); mccCopy(f,frevgg_vector); for(int j0;j(int)(nfft/21);j) { datap[j]mccGetRealVectorElement(Pxx, (j1));//功率谱密度存于datap[]数组 dataf[j]mccGetRealVectorElement(f, (j1));//相应频率存于数组dataf[]中 } mccFreeMatrix(Pxx); ………………. SendMessageBox(WM_PAINT,0,0);//利用Vc下的图形函数画图 Return; } 如上生成的程序可读性不太好而生成的c代码则可读性较好但千万注意只能用 Matlab的MATH库不可用c的MATH库否则编译会出错限于篇幅在此不述。 3利用Matcom调用工具箱中的函数 Matcom 编译M文件先将M文件按照与Matcom的cpp库的对应关系翻译为cpp源代码然后用对应版本的c编译器将cpp文件编译成相应的exe或dll文 件所以第一次运行要指定c编译器的路径否则无法编译指定好的编译信息就写在Matcom\bin\matcom.ini文件中不过这一步按装 matcom时它自动寻找编译器并将其写入matcom.ini文件中matcom4.5版中使用TeeChart3.0 OCX控件因而它支持图形操作。 我们依然用上述的testwin.m文件不要将图形函数注释掉利用Mideva来生成可被Vc调用的信号处理程序。 运行 Mideva在主界面上直打开M文件在菜单中选择compile to dll,输入testwin..在Matcom debug目录下可以找到这样的几个文件testwin.c ,testwin.h,testwin.cpp,testwin.lib,testwin.dll,testwin.exp等。 将上述testwin.cpp和testwin.h加入工程中project/add to project/files并且在相应的文件中加入”stdafx.h” 加连接库Tools\option\directory\ 选include选项,加入e:\matcom45\lib (包含matcom.h) library选项加入e:\matcom45\lib 4) project\add to project\files 文件类型选项选.lib将e:\matcom45\lib\v4501.lib加入工程中编译运行。相应代码如下 void CtestmatcomDlg::OnpsdButton(){ double datap[512],dataf[512]; initM(MATCOM_VERSION);//初始化matcom库 Mm Fs,nfft,noverlap;//创建矩阵 Mm xzeros(1,1024); Fs1024;nfft1024;noverlap128; dMm(Pxx_o);dMm(f_o);//创建并命名矩阵 datax[];//数据采集的数据存于此数组中 for(int i1;i1024;i) { x.r(1,i)datax[i1];//给x阵赋值 } testwin(Fs,nfft,noverlap,x,i_o,Pxx,f_o);//matcom生成的函数 for(i0;i513;i){//取出功率谱密度分析结果 dataf[i]f_o.r(i1,1); datap[i]Pxx_o.r(i1,1);} exitM(); return; } 可见利用Matcom进行M文件转换非常的容易生成的代码可读性很好以上的转换同时生成了可供Vc调用的动态连接库其使用和一般的动态库一样使用。 同时需指明Matcom不仅可转换独立的不依赖于其它M文件的M文件同时可转换调用其它M文件的M文件嵌套。条件是这此M文件在同一个目录下面如前所 述的psd.m可直接用上述方法转换生成了多个重载形式的psd函数 结论 利用Mtlab引擎调用工具箱中的函数可节省大量的系统资源应用程序整体性能较好但不可脱离Matlab 的环境运行。用Matlab编译器进行工具箱函数的调用须转换相应的文件使其成为独立的文件且不支持图形函数转换的代码可读性不太好。用 Matcom 进行转换非常方便生成的代码可读性很好支持图形函数且代码执行的速度比不转换平均要快 1.5 倍以上。以上程序在Vc 6.0, Matlab 5.2, Matcom 4.5 中调试通过,以上方法在工程实践中已得到很好的运用。 通过 VC 实现对 MATLAB 的调用 成都 .中国科学院光电技术研究所 邮编610209 齐 波 董能力 一 引言 众所周知MATLAB是功能非常强大的数学软件它广泛应用于线性代数、自动控制理论、数理统计、数字信号处理、时间序列分析、动态系统仿真等领域。因 此如果把MATLAB的程序加入到自己的VC、VB、POWER STATION及其它语言编制的程序中将大大减少编程的工作量、保证程序的准确性并且继承VC良好的用户界面。下面就以VC 为例介绍一下它的外部调用。 二 程序实现 --作者实现外部调用的思路是首先将m文件加入到一段C程序中,然后通过MATLAB中的mex批处理文件将该C文件生成exe文件然后通过VC的外部调用的函数shellexec()或winexec实现调用。 mex批处理文件的调用格式如下 mex -f msvc60engmatopts.bat *.c c文件的格式如下: /* engwindemo.c * This is a simple program that illustrates how to call the MATLAB * Engine functions from a C program for windows * Copyright (c) 1996-1998 by The MathWorks, Inc. * All Rights Reserved.*/ i nclude windows.h i nclude stdlib.h i nclude stdio.h i nclude string.h i nclude d:\matlab\extern\include\engine.h void main() { Engine *ep; /* * Start the MATLAB engine */ if (!(ep engOpen(NULL))) { MessageBox ((HWND)NULL, (LPSTR) Cant start MATLAB engine, , MB_OK); exit(-1); } engEvalString(ep, contour(peaks)); engClose(ep); } - 程序中的黑体部分即为要加入的m文件的位置。这样就生成了与m文件同名的exe文件,通过VC中的外部调用函数便很容易的实现了对MATLAB的调用。 三 结 论 本文给出了VC等高级程序语言调用MATLAB中程序函数的方法融合了VC与MATLAB两种不同的语言大大提高了编程效率。不失为一种较好的程序设计方法。 Matcom: Matlab 与 C 结合的有效途径 林 岚* 周云波 杨玉星 林家瑞 作者单位华中理工大学生物工程系武汉 430074 *男24岁硕士研究生 摘 要 本文首先介绍了当前在国内外十分流行的工程设计和系统仿真软件包Matlab的优缺点然后展开介绍了Matcom(一种将Matlab与C结合的工具)的功能及如何使用最后对其效果进行了总结。 关键词 Matlab Visual C Matcom ECG 1 工程设计软件Matlab特点分析 Matlab 是MathWorks公司于1982年推出的一套高性能的数值计算和可视化软件。它集数值分析、矩阵运算、信号处理和图形显示于一体构成了一个方便、界 面友好的用户环境。它还包括了ToolBox(工具箱)的各类问题的求解工具可用来求解特定学科的问题。其特点是 (1)可 扩展性Matlab最重要的特点是易于扩展它允许用户自行建立指定功能的M文件。对于一个从事特定领域的工程师来说不仅可利用Matlab所提供的 函数及基本工具箱函数还可方便地构造出专用的函数从而大大扩展了其应用范围。当前支持Matlab的商用Toolbox(工具箱)有数百种之多。而由 个人开发的Toolbox则不可计数。(2)易学易用性Matlab不需要用户有高深的数学知识和程序设计能力不需要用户深刻了解算法及编程技巧。 (3) 高效性Matlab语句功能十分强大一条语句可完成十分复杂的任务。如fft语句可完成对指定数据的快速傅立叶变换这相当于上百条C语言语句的功 能。它大大加快了工程技术人员从事软件开发的效率。据MathWorks公司声称Matlab软件中所包含的Matlab源代码相当于70万行C代码。 由于Matlab具有如此之多的特点在欧美高等院校Matlab已成为应用于线性代数、自动控制理论、数理统计、数字信 号处理、时间序列分析、动态系统仿真等高级课程的基本教学工具在研究单位、工业部门Matlab也被广泛用于研究和解决各种工程问题。当前在全世界有 超过40万工程师和科学家使用它来分析和解决问题。 然而Matlab自身所存在的某些缺点限制了它的应用范围。 (1) Matlab是一种解释性语言因此它的实时效率是相当差的。例如在笔者所从事的一个心电信号处理项目中采用Matlab语言来处理5分钟的心电数据 在486/66系统机上需要25分钟而同样的算法用C语言实现仅需30多秒。由此可见Matlab的语言执行效率是比较低的。 (2)Matlab程序不能脱离其环境运行因此它不能被用于开发商用软件。 (3)Matlab程序可以被直接看到 2 Matcom:Matlab与C的完美结合 MathTools公司推出的Matcom(可于http://www.mathtools.com处获取)可以说是以上问题的完美解决。它可将Matlab的源代码译成同等功能的C源码。既保持了Matlab的优良算法又保持了C的高执行效率。 下面将详细介绍如何使Matlab与C接口。 运行环境 Matcom 3.0 Matlab 5.1 Visual C 5.0 中文Windows 95 PC:486/66 (1)首先应设置Matcom所对应的编译器类型、数据类型。 (2)将你所需要的.M文件翻译成C源码。 在这里将用一个简单的滤波器Matlab源程序 Lin.m b1 2 1; a1 -1.58 0.64;n50; x1, ones(1,n-1); yfilter(b,a,x); plot(y./70,*); hold on plot(x,.); grid; 下面给出了经Matcom翻译后的C源程序。Lin.cpp M b(b,0,0); M a(a,0,0); M n(n,0,0); M x(x,0,0); M y(y,0,0); b(BR(1.0),2.0,1.0); a(BR(1.0),-1.58,0.64); n50.0; x(BR(1.0),ones(1.0,n-1.0)); yfilter(b,a,x); plot(rdivide(y,70.0),TM(*)); hold(TM(on)); plot(x,TM(.)); grid(); (3)Visual C环境设置。 在Visual C中的Project / Settings / C, C / Preprocessor /Additional include subdirectories 中填入当前Matcom所处的路径.。如c:\matcom\在Visual C中的工程窗口处 Project / Add to Project / Files.加入mlibvc0.lib库文件。 (4)修改C源代码。 注意 ①在头文件处应包含matlib.h. #define MLIB 0 i nclude matlib.h. ②在类成员函数CMfcApp::InitInstance中调用. InitM启动对Matlab函数的调用。 BOOL CEcgstarApp::InitInstance() { TRACE0(initM\n); initM(stin,stout,sterr); ...... } ③在类构造函数CMfcApp::CMfcApp.中不要调用任何Matlab函数 ④在类构造函数CMfcApp::CmfcApp中调用exitM结束对Matlab函数的调用。 CEcgstarApp::CEcgstarApp() { exitM(); } ⑤在程序中合适的位置插入经Matcom翻译过后的C源码。 ⑥编译工程文件就可得到你所需的结果。 3 结束语 笔者在从事生物医学工程ECG信号的检测与处理项目中对采用不同方法完成同一任务在代码量和运行时间上进行了比较如表1、表2所列。 表1 ECG检测核心算法代码量 全部用C编写 全部用Matlab编写 用Matcom转换后的C编写 约3400行 约400行 约600行 表2 ECG检测核心算法运行时间 全部用C编写 全部用Matlab编写 用Matcom转换后的C编写 约30秒 约25分钟 约1分钟 由此可见采用Matcom进行程序设计这是一种时间、效率上的极好的折衷它使得你可以将更多的时间放在项目关键问题的思考上而不是放在算法的实现和程序的编码中对于广大工程技术人员的开发工作是十分有益的。 Matlab 和 C 接口中函数注册的实现 李江红 韩正之 《计算机应用》COMPUTER APPLICATIONS 2000 Vol.20 No.4 P.18-20 作者简介李江红(1970-)男湖南长沙人博士研究生主要研究方向随机决策以及智能控制韩正之1947-男上海人教授主要研究方向非线性控制以及智能控制。 作者单位李江红上海交通大学智能工程研究所 上海 200030 韩正之上海交通大学智能工程研究所 上海 200030 摘 要函数注册在Matlab和C接口中起着重要的作用。在介绍函数注册作用的基础上详细分析了函数注册的过程及应当注意的问题并给出了一种实现函数注册的最简单的方法。用实例展示了函数注册的具体实现过程。 关键词MatlabC函数注册 中图分类号TP317,TP319 文献标识码A 文章编号1001-9081(2000)04-0018-03 FUNCTION REGISTERING IN THE INTERFACE BETWEEN MATLAB AND C LI Jiang-hong HAN Zheng-zhi Intelligent Engineer Research Institute of Shanghai Jiaotong University, Shanghai 200030 China Abstract: Function registration plays an important role in the interface between Matlab and C. This paper analyzes the procedure of function registering. Each step of function registering is discussed in detail in the paper, and at the endan example is given for illustration. Key words:Matlab; C; function registration 1 研究意义 Matlab为用户提供了丰富的Windows图形界面设计方法使用户能够在利用其强大数值计算功能的同时设计出友好的图形界面。在编程效率、可读 性、可移植性和可扩充性上Matlab远远优于其它高级编程语言。Matlab能够设计出功能强大、界面优美、性能稳定的高质量程序它受到了越来越多 用户的欢迎。然而作为一种以解释方式运行的高级计算机语言Matlab程序的执行效率较低。为了解决这一问题MathWorks公司提供了 Matlab和C的接口。MathWorks公司提供的Matlab和C的接口方式共有三种(a)将Matlab程序编译成MEX文件C或C文件 (b)在C,C程序中利用Matlab Engine调用Matlab函数(c) 在C,C程序中利用Matlab C Math Library或Matlab C Math Library调用Matlab函数。其中通过方式(a)、(b)生成的程序只有在安装了Matlab系统上才能正常运行而由方式(c) 生成的程序则没有这样的要求它能够以独立执行程序的形式运行即使客户没有安装Matlab系统。方式(c)唯一的缺点就是不能利用Matlab中丰富 的图形句柄处理函数但是对于VC等开发工具而言这不是一个很严重的问题。因此方式(c)是实现功能和效率兼顾的最好接口方法2。 当用方式(c) 生成应用程序时一个重要的问题就是那些以函数作为自身输入参数的函数实现问题。众所周知Matlab提供了一组能完成极值及极值点计算线性规划二次规划以及非线性方程求解等数值运算的优化函数3。 在Matlab中使用这组优化函数时用户定义的待优化函数必须作为输入参数传递给这些函数。在优化函数运行的过程中系统将最终执行用户定义的待优化 函数并且这一切无须程序员的参与。但是当程序员通过方式(c)在C程序中调用Matlab C Math Library中的优化函数时事情就变得比较复杂。要利用这些优化函数所提供的数值计算功能保证用户定义的待优化函数真正得到执行程序员就必须自己 完成对待优化函数的注册。因此函数注册的研究具有重要的实用价值。 2 Matlab和C接口中函数注册 在C程序中当调用优化函数等以函数为输入参数的函数时Matlab C Math Library调用Matlab C Math Library中的mlfFeval()来执行作为参数传递的函数。在mlfFeval()中又是通过对转换函数的调用来真正地执行作为参数传递的函数。 转换函数和映射表是这一过程能够顺利进行的重要原因。函数注册就是定义函数的转换函数并建立相应的它的映射表。对于Matlab C Math Library中的函数MathWorks公司都定义了它们转换函数并建立了它们的映射表完成了对它们的注册。但是对于用户自定义的函数程序员就必 须自己完成这项工作。 函数注册可以分成(1)定义待注册函数(2)定义转换函数(3)建立映射表(4)初始化映射表等以下四个部分来完成。下面将对各个部分进行详细地介绍。 (1) 定义待注册函数 待注册函数因用户要求而异。为便于后面的分析设用户定义的函数为 mwArray MyFunc(mwArray x){ ……//函数体。 } 注意待注册函数的输入、输出参数的类型必须是mwArray。mwArray是Matlab C Math Library中最基本的数据类它对应Matlab中的基本编程单位—数组。 (2) 定义转换函数 转换函数的功能是完成Matlab C Math Library和用户函数之间的翻译。由于它面向Matlab C Math Library因此必须用C定义。对(1)中定义的待注册函数其转换函数的一般形式如下为简单起见该转换函数忽略了错误处理代码 typedef mwArray (*PMYFUNC) (mwArray); extern C { int MyThunk (mlfFuncp pFunc, int nArgOut, mxArray ** ArgOut, int nArgIn, mxArray ** ArgIn){ mwArray tmpmwArray(ArgIn0,0); mwArray Out(*((PMYFUNC)pFunc)) (tmp); ArgOut0Out.FreezeData( ); return 1 } } 转换函数共有5个输入参数以MyThunk为例pFunc是指向待注册函数的指针nArgIn、nArgOut, 分别是待注册函数的输入、输出参数的个数 ArgIn、ArgOut,则分别是输入、输出参数构成的数组。其中ArgIn0对应第1个输入参数ArgIn1对应第2个输入参数……。 ArgOut的情形类似。 由于转换函数面向Matlab C Math Library因此它的输入、输出参数中的数组类型只能是mxArray (mwArray是Matlab C Math Library中基本的数据它对应Matlab中的基本编程单位—数组)而注册的函数又只能接受mwArray类型的参数。因此在调用注册函数之前 必须将mxArray型数据转化为mwArray型数据如MyThunk中mwArray tmpmwArray(ArgIn0,0); 在转换函数返回之前必须将注册的函数的返回值由mwArray型转化为型mxArray如MyThunk中ArgOut0 Out.FreezeData()。 (3) 建立映射表 映射表的作用是把待注册函数的名称映射到指向该函数的指针。映射表中的元素由三元组函数名称、函数指针、转换函数构成。对(1)、(2)中定义的待注册函数和转换函数相应的映射表为 static mlfFuncTabEnt MfuncTab{ {MyFunc, (mlfFuncp) MyFunc, MyThunk} {0, 0 ,0} } 其中mlfFuncTabEnt是Matlab C Math Library中用于存储函数项的数据结构。{0, 0 ,0}表示映射表的结束。 (4) 初始化映射表 初始化映射表的方式比较单一。例如对(3)中的映射表程序段 class feval—init{ feval—init{mlfFevalTableSetup(MfuncTab);} static feval—init feval—setup; } feval—init feval—init::feval—setup; 将完成其初始化。其中mlfFevalTableSetup是Matlab C Math Library中用于初始化映射表的函数。设置静态对象的目的是保证映射表初始化在系统初始化静态变量时就得以完成。 从上面的分析可以看出函数注册的过程比较复杂。不过MathWorks公司注意到了这个问题它定义并提供了DECLARE—FEVAL— TABLE, EVAL—ENTRY, END—FEVAL—TABLE等一组宏来帮助用户简单、轻松地完成函数注册。例如对于(1)中定义的函数MyFunc程序段 DECLARE—FEVAL—TABLE FEVAL—ENTRY(MyFunc) END—FEVAL—TABLE 就实现了对MyFunc的注册它取代了(2)、(3)、(4)中的所有工作。事实上只要待注册函数的输入参数数目不大于8输出参数数目不大于5就能用这组宏来完成函数注册。 3 应用实例 下面的VC程序通过调用Matlab C Math Library中的fmin()计算函数 f(x,y)ex(4x22y24xy2y1) 在y2时位于区间-22中使函数值最小的自变量x的值。 i nclude matlab.hpp i nclude stdlib.h /***(1) 定义注册函数 ***/ mwArray MyFunc(mwArray x,mwArray y){ mwArray mResultexp(x)*(4*x ^ 22*y ^ 24*x*y2*y1); return mResult; } /***(2) 定义转换函数 ***/ typedef mwArray (*PMYFUNC)(mwArray,mwArray); extern C{ int MyThunk(mlfFuncp pFunc, int nArgOut, mxArray ** ArgOut,int nArgIn, mxArray **ArgIn) { mwArray tmp1mwArray( ArgIn0, 0 ); mwArray tmp2mwArray( ArgIn1, 0 ); mwArray Out(*((PMYFUNC)pFunc))(tmp1,tmp2); ArgOut0Out.FreezeData(); return 1; } } /***(3) 建立映射表 ***/ static mlfFuncTabEnt MFuncTab { { MyFunc, (mlfFuncp)MyFunc, MyThunk }, { 0, 0, 0 } }; /***(4) 初始化映射表 ***/ class feval—init { feval—init() { mlfFevalTableSetup( MFuncTab ); } static feval—init feval—setup; }; feval—init feval—init::feval—setup; /***可以取代(2)(3)(4)的宏注册函数 ****/ /*** DECLARE—FEVAL—TABLE ***/ /*** FEVAL—ENTRY(MyFunc) ***/ /*** END—FEVAL—TABLE ***/ /***** 主程序 *****/ void main(void){ mwArray mStart,mEnd,mP,mOption; mStart-2,mEnd2;mP2.0; mwArray mResultfmin(MyFunc,mStart,mEnd,mOption,mP); cout mResult endl; } 参考文献 1 薛定宇. 控制系统计算机辅助设计—MATLAB语言及应用M.北京:清华大学出版社 1996.17-19. 2 MATLAB C math Libarary User′s GuideZ. The Math Works, Inc., 1998.2-18. 3 施阳,李俊.MATLAB语言工具箱—TOOLBOX实用指南M.西安:西北工业大学出版社1998.100-101. 收稿日期:1999-10-19 Matlab 与 C 混合编程 Matlab 是当今世界上使用最为广泛的数学软件它具有相当强大的数值计算、 数据处理、系统分析、图形显示甚至符号运算功能是一个完整的数学平台在这个平台上你只需寥寥数语就可以完成十分复杂的功能大大提高了工程分析计 算的效率。另外由于Matlab的广泛使用于是出现了为各个领域专门使用的工具箱(即在某一研究领域常用数学工具的函数包)这些工具箱的出现更加促进 了Matlab的流行。 Matlab强大的功能只能在它所提供的平台上才能使用也就是说你必需在安装有matlab系统的机 器上使用.m文件这样就给工程计算带来了很大不便特 别是在matlab中使用的行解释方式执行代码这样大大地限制了代码执行速度。 于是人们想到能否开发一个matlab与其他高级语言的接口这样就可以把matlab 的强大功能融入各种应用程序中并且通过高级语言编译器编译为2进制代码 从而大大提高了执行速度。 于是matlab的5.1 版本提供了自带的C Complier同时MathTools公司也为 Matlab开发了m文件高效解释和调试IDEMIDEVA。经过近两年的发展matlab 5.3 中的C complier--mcc版本已经为2.0,而MIDEVA最新版本为4.5。 将matlab与C混合编程大概有如下三种方法 用Matlab的mcc将.m文件翻译为cpp源文件然后在C编译器中调用 也可以用mcc编译编译为stand-alone程序。 用MatcomMIDEVA将.m文件翻译为cpp代码并编译为exe或dll 文件。 按照matcom的语法在VC或BCB中直接书写matlab语句(与matlab 很相似)这也是我最喜欢用的方法。 方法1和2/3各有利弊1不支持图形(支持图形的库国内现在还没有D) 1对类支持也不够2支持绝大多数的matlab语句(包括图形)但对于struct等的支持也有缺陷。 MATLAB5.3 的提供了C/C数学库其中的C数学库功能很强使用它可以用类似MATLAB 的语法编写C程序十分方便。虽然速度上仍然比手工C/C程序慢但是由此换来的高效的开发效率和可靠性往往是值得的。另外mcc命令可以将M文 件转化为C或CPP文件编译后可以脱离MATLAB运行 它们也是使用的C/C数学库。 不过MATLAB的数学库在开发时似乎倾向于编译独立的可执行程序把VC、BC只是作为一个编译和连接的工具而没有过多地考虑在VC、BC的集成环 境下进行开发。这给我们带来了不便。 很多网友问起如何将MCC生成的C程序嵌入到VC。最近对这个问题做了一下尝试在这里做一个总结请大家回去试试。这里只介绍VC的情况用BC的 网友就自己研究研究吧估计是类似的。 1、设置项目编译选项 首先建立一个新的项目或者打开一个已有的项目然后选择菜单 Project-Settings-C/C Category:Preprocessor Preprocessor definitions: 添加: MSVC,IBMPC,MSWIND Category: Precompiled Headers 选择: Automatic use of precompiled headers Through header: stdafx.h 2、调设置项目连接选项 首先要从下面几个函数定义文件(*.def)生成相应的导入库文件(*.lib) libmmfile.def libmcc.def libmatlb.def libmx.def libmat.def 它们位于目录c:\matlab\extern\include 用下面命令导出库文件: lib /def:libmmfile.def /out:libmmfile.lib /machine:ix86 lib /def:libmcc.def /out:libmcc.lib /machine:ix86 lib /def:libmatlb.def /out:libmatlb.lib /machine:ix86 lib /def:libmx.def /out:libmx.lib /machine:ix86 lib /def:libmat.def /out:libmat.lib /machine:ix86 将它们放入你的项目连接选项 Project-Settings-Link Category:Input Object/library modules: 添加:libmatpm.lib libmmfile.lib libmcc.lib libmatlb.lib libmx.lib libmat.lib 注1: 中间是空格不要加逗号 注2: libmatpm.lib是C MathLib的库如果是只用C就不用连接它了。 Ignore libraries: 添加: msvcrt.lib 注: 仅在Debug版本中需要。原因不明. 3、设置编译环境 Tools-Options-Directories Include fiels添加: c:\matlab\extern\include c:\matlab\extern\include\cpp Library fiels添加: c:\matlab\extern\lib c:\matlab\extern\include 注:下面这个目录是那些lib所在的地方。 如果都挪到上面的目录这个自然就不要了。 4、编写程序 用MCC命令生成的CPP文件和自己手工编写的CPP文件, 其项目设置是完全相同的, 程序的语法原则上也是一样的. 只是MCC生成的CPP文件有大量没用的代码. (1)添加自己编写的程序模块 用下面文件头: i nclude stdafx.h i nclude matlab.hpp 然后, 按照C MathLib文档要求的格式书写程序. (2)嵌入mcc生成的文件 在MATLAB下用下面格式的命令生成cpp文件 mcc -t -L Cpp test 得到test.hpp, test.cpp 将test.cpp加入项目, 不做任何改动. 最后摁F7编译就可以了。 5、实例 上面罗罗嗦嗦一大堆肯定让你打哈欠了:没关系其实还是挺简单的这里有个VC的project用C数学库解决了一个幼儿园的算术题. 这里说明一下 MATLAB程序test.m: function [sum, prod]test(x,y) sum xy; prod x*y; 用来计算两个数的和与积。注意这是两个返回变量的情况。 另外x,y当然可以是数组。 用mcc命令生成了test.hpp和test.cpp。 文件demo.cpp: i nclude stdafx.h i nclude matlab.hpp i nclude test.hpp void mccDemo() { CString str; mwArray x, y, sum, prod; double dx,dy,dsum,dprod; x 5.0; y 10.0; sum test(prod, x, y); dxx(1,1); dyy(1,1); dsumsum(1,1); dprodprod(1,1); str.Format(%f%f%f\n%f*%f%f, dx,dy,dsum,dx,dy,dprod); AfxMessageBox(str); } 由于采用了C数学库语法很简单。注意数组的赋值、其中数据的存取这些都要仔细地看手册。 最后是跳出一个消息框显示计算结果。 VC 中编译 MEX 程序 1. 目的 一般情况下我们都是在MATLAB命令行或DOS命令行下编译MEX程序。 所用的命令就是mex filename.c 这有很多不方便的地方 a. 虽然mex也可以编译C的mex程序但是它的主框架仍是C的 a. 当程序有多个模块时需要多次使用mex命令操作很麻烦 b. 不能利用VC特有的ClassWizard自动创建和维护类 c. 不能用MFC类库编写应用程序 d. 不能方便地进行类似VC的项目管理 这样一个命令行的编程环境可能会大大束缚你的想象力... 其实解决问题的方法很简单下面以VC6环境为例详细解说如何在IDE中编译MEX程序。 2. 步骤 (1)准备工作 (这里假设MATLAB的路径为C:\MATLAB) a. 由matlab.def创建库文件matlab.lib 进入c:\matlab\extern\include目录用lib命令生成matlib.lib C:\cd \matlab\extern\include C:\MATLAB\extern\includelib /def:matlab.def /out:matlab.lib Microsoft (R) Library Manager Version 6.00.8447 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. LIB : warning LNK4068: /MACHINE not specified; defaulting to IX86 Creating library matlab.lib and object matlab.exp C:\MATLAB\extern\include 警告信息不用理它。 b. 修改mex.h 该文件也在C:\MATLAB\extern\include目录 找到这一行void mexFunction( 替换为 __declspec( dllexport ) void mexFunction( 另保存为 mex_vc.h (2)启动VC创建MFC AppWizard(dll)程序框架 (3)设置系统选项 a. 设定头文件和库文件路径 菜单Tools-Options-Directories Include files:添加c:\matlab\extern\include Library files:添加c:\matlab\extern\include b. 设置编译连接选项 菜单Project-Settings C/C-Preprocessor definitions: 添加MATLAB_MEX_FILE Link-Object/Library modules: 添加matlab.lib 注1. 其它优化、调试以及头文件、库文件等选项看情况调整 注2. Release版在General-Microsoft Foundation Classes选项中 必须设置为Use MFC in a Static Library. 原因不明 (4)编写DLL主程序 a. 文件名要用.cpp为扩展名头两行必须是 i nclude stdafx.h i nclude mex_vc.h b. 编写mexFunction函数用如下格式声明 void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { ... } (5) 象普通VC的DLL程序一样继续编写其它部分程序加入其它模块 (6) 调试错误用F7编译生成DLL。我的例子 --------------------Configuration: MatWave - Win32 Release-------------------- Compiling resources... Compiling... StdAfx.cpp Compiling... MatWave.cpp sample.cpp mex.cpp Generating Code... Linking... Creating library Release/MatWave.lib and object Release/MatWave.exp LINK : warning LNK4089: all references to SHELL32.dll discarded by /OPT:REF LINK : warning LNK4089: all references to comdlg32.dll discarded by /OPT:REF MatWave.dll - 0 error(s), 2 warning(s) 大功告成有两个警告不理它。 拿到MATLAB里面试试吧不过要有非法操作和异常退出的心理准备哦. 另外如果要在MATLAB运行中重新编译DLL需先执行: clear mex CBuilder与Matlab混合编程的实现 长沙 张云洲 在CBuilder中调用Matlab工具箱函数有两种实现方式。一种是基于Matlab环境支持通过必要的设置实现笔者在本刊上曾撰文对这种 方式进行了专门的阐述。另一种则是完全脱离Matlab环境通过动态连接库方式实现对Matlab工具箱函数的调用这可以通过一种开发平台 Mediva来实现。相对来说前者的限制因素较多而后者则较为方便灵活。 一、Mediva软件平台 Mediva是Mathtools公司推出的一种Matlab编译开发软件平台提供对Matlab程序文件M文件的解释执行和开发环境支持。该软件 有为Borland C、Visual Basic和Dephi等编程语言开发的不同版本目前其版本已经到了4.5版。软件大小仅6.5M可以通过访问其站点 www.mathtools.com免费下载试用一个月。 Mediva软件平台本身的功能相当强大提供近千个Matlab的基本功能函数通过必要的设置就可以直接实现与C的混合编程而不必再依赖 Matlab同时Mediva还提供编译转换功能能够将Matlab函数或编写的Matlab程序转换为C形式的DLL从而实现脱离 Matlab环境对Matlab函数和过程的有效调用这样就有可能实现对Matlab强大的工具箱函数的利用。 Mediva的 缺点是C与Matlab混合编写的应用软件必须携带必要的DLL从而增大了软件的体积约4M同时也不能对所有的Matlab函数提供支持例 如采用类库进行设计的部分函数。但尽管如此对于控制系统计算机设计、分析的工作来说Mediva仍不失为一个好的工具。 由于利用Mediva将Matlab工具箱函数转换成DLL的内容较多限于篇幅本文在此仅给出对Matlab函数直接调用的实现而将另撰文阐述DLL的实现。 二、CBuilder直接调用Matlab函数 本文假设已经安装了Mediva软件或已经得到必要的两个动态连接库mdv4300.dll和ago4300.dll。 Mediva提供的近千个Matlab基本功能函数都可以在CBuilder中直接调用。这些函数包括基本的操作、命令、I/O、线性代数、位 图、控制等基本上可以满足我们的一般需要。当然其最大的优点就是可以直接在CBuider中直接调用而不必考虑安装庞大的Matlab。 其实现方式和步骤如下 1Lib文件的生成 在Dos下用CBuilder中的Implib.exe通过如下命令生成mdv4300.lib: implib mdv4300.lib mdv4300.dll 将上述两个DLL文件和此Lib文件拷贝到当前目录下。 2实现与Matlab的混合编程 Matlab.h包含了Mediva中所有类型、常量、函数的说明和定义必须将此头文件放于程序的第一行。Mediva给出的Matlab函数形式并 不特殊如绘线函数Plot在Mediva中说明为Mm DLLI plot(cMm varargin)varargin与Matlab 中的意义是一样的与输入变量的个数相对应。所有可以直接使用的函数都在Matlib.h头文件中定义而在mdv4300.dll中实现。 但在CBuilder中使用Mediva提供的Matlab函数的格式与Matlab编程稍有不同这主要体现在C中必须进行必要的说明上。 例如我们要用绘线函数Plot来绘制数组x[100]的红色图线。在Matlab中调用为Plot(x,r)在C中调用则为Plot(CL (x),TM(r))其中CL是一个关键字是多变量输入时所必须使用的用以指明调用的变量而TM则指明这是一个字符。 下面我们给出一个示例程序其功能是对一个1024点的输入数组进行FFT 变换并绘制变换后频谱实部的火柴杆图最后将原数据和变换后的数据写入数据文件中。 i nclude matlib.h //必须包含的头文件 i nclude vcl.h #pragma hdrstop i nclude TryMatcomU.h #pragma package(smart_init) #pragma resource *.dfm TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } void __fastcall TForm1::Button1Click(TObject *Sender) { int k0; initM(MATCOM_VERSION); //必须进行的初始化 Mm cur1,cur2; //定义变量 cur1zeros(128); cur2zeros(128); //变量初始化 for (k1;k 128;k) cur1.r(k)randM(); //生成一个随机数列 figure(1); plot(cur1);//图形显示该数列 cur2fft(cur1,128); //做128点fft变换 figure(2); //绘制fft变换后实部的火柴杆图注意此处多变量输入的格式 stem((CL(cur1),real(cur2),TM(r))); fidfopen(filename,mode,format) opens exitM(); //退出调用 } 如果完全使用C来实现本程序的工作其代码将超过300行由此可以看出CBuilder与Matlab函数的混合编程可以给我们带来多么大的方便 3变量内部状态/数据的观察方法 Mediva使用的所有变量均定义为Mm类型。如果在CBuilder中观察Mm类型变量的内部状态/数据要稍麻烦一些。但在调试程序时这又是不可避免的一步这里举例给出变量观察的方法。 例如对上面生成的cur2数列进行观察 *cur2.pr 0.1892 cur2(1)的实部 *cur2.pi 0.0013 cur2(1)的虚部 三、CBuilder调用Matlab工具箱函数转换后的DLL 1Matlab函数向DLL的转化 Mediva软件提供了将Matlab函数转换为DLL的功能非常方便。但需要注意的是 1.Matlab5.0以上版本所有带有tf类的函数均无法转换 2.Matlab4.2以下版本多数函数能够转换但转换后大多不能直接使用而必须加以处理。 MATCOM V4.3中把含有输入参数的M文件转换成DLL时,生成的DLL无法调用.以.M为例, function [x1,x2]flower(x3) MATCOM生成的FLOWER.CPP和FLOWER.H中声明为: Mm flower(Mm x3, i_o_t, Mm x1__o, Mm x2__o) { begin_scope x3.setname(x3); ... } Mm flower(Mm x3); Mm flower(Mm x3, i_o_t, Mm x1__o, Mm x2__o); 而生成的G_FLOWER.CPP声明为: ---- void DLLX _stdcall flower_1_1(Mm** in01, Mm **out01) ---- void DLLX _stdcall flower_1_2(Mm** in01, Mm **out01, Mm **out02) ---- 其中对于in01的说明是不正确的.应按如下修改。然后按如下MAKE文件进行编译。 # # MATCOM makefile # all: flower.dll g_flower.obj: g_flower.cpp bcc32 -c -Id:\matcom43\ -WD -Id: \matcom43\lib -Hmatlib.csm -a4 -5 -eg_flower.obj g_flower.cpp flower.dll: flower.obj g_flower.obj bcc32 -Ld:\matcom43\ -WD -Id: \matcom43\lib -Hmatlib.csm -a4 -5 -eflower.dll flower.rsp d:\matcom43\lib\mdv4300b.lib 在CPP中调用这个函数之前一定要先给in01分配空间。 i nclude matlib.h #pragma hdrstop i nclude flower.h #define WIN32_LEAN_AND_MEAN i nclude windows.h i nclude matlib.h #pragma hdrstop extern C { void DLLX _stdcall flower_1_1(Mm in01, Mm **out01) { *out01new Mm(); //*in01new Mm(); **out01flower(in01); exitM(); } void DLLX _stdcall flower_1_2(Mm in01, Mm **out01, Mm **out02) { *out01new Mm(); *out02new Mm(); //*in01new Mm(); flower(in01, i_o , **out01, **out02); exitM(); } VC调用MATLAB Engine 实验环境: Pwin98, MATLAB5.3, Visual C 6.0 SP3 1 生成几个连接库文件 在目录 c:\matlab\extern\include 下找这几个文件: libeng.def libmx.def libmat.def 在DOS行命令下生成三个库文件: c:\msdev\bin\lib /def:libmat.def /out:libmat.lib c:\msdev\bin\lib /def:libeng.def /out:libeng.lib c:\msdev\bin\lib /def:libmx.def /out:libmx.lib 把生成的三个LIB文件加入你的LINK项 libeng.lib libmx.lib libmat.lib 2 写包含engine功能的文件 可以参考: c:\matlab\extern\examples\eng_mat\engwindemo.c 注意: 可以用.CPP做后缀. 比如:MATLAB.CPP 3 设置编译选项 把MATLAB.C加入你的PROJECT MATLAB.C的开头加入两行 i nclude stdafx.h i nclude engine.h 包含其它头文件, 自己看情况而定 4 编写调用engine的函数 比如响应菜单调用自己的函数matlabPlot而此函数的实现在matlab.cpp文件中实现内容如下 i nclude stdafx.h i nclude engine.h int MatlabDraw() { Engine *ep; if (!(ep engOpen(NULL))) { MessageBox ((HWND)NULL,Cant start MATLAB engine,Matlab Draw,MB_OK); return 0; } engEvalString(ep, x0:0.01:2*pi;ysin(x);plot(x,y);); engEvalString(ep, title(Matlab Drawing);); engEvalString(ep, xlabel(X);); engEvalString(ep, ylabel(Y);); MessageBox(NULL, Press any key …,MATLAB Draw,MB_OK); engClose(ep); return 1; } 5 设置其它编译连接选项 PreProcessor 加上: MATLAB_MEX_FILE INCLUDE 加上: c:\matlab\extern\include LIB 加上: c:\matlab\extern\include 最后如果有必要的话在DOS命令行运行: MATLAB /regserver 本文转自博客园知识天地的博客原文链接转]MATLAB 与 C 语言的接口如需转载请自行联系原博主。