Matlab与C/C++混合编程接口及应用

发布者:技术掌门最新更新时间:2011-10-28 关键字:Matlab  混合编程 手机看文章 扫描二维码
随时随地手机看文章

  1 引言

  Matlab 是当前应用最为广泛的数学软件,具有强大的数值计算、数据分析处理、系统 分析、图形显示甚至符号运算等功能[1]。利用这一完整的数学平台,用户可以快速实现十分 复杂的功能,极大地提高工程分析计算的效率[2][3]。但与其他高级程序[3]相比,Matlab 程序 是一种解释执行程序,不用编译等预处理,程序运行速度较慢[4]。

  C/C++语言是目前最为流行的高级程序设计语言之一[5]。它可对操作系统和应用程序以 及硬件进行直接操作,用C/C++语言明显优于其它解释型高级语言,一些大型应用软件如 Matlab 就是用C 语言开发的。

  在工程实践中,用户经常遇到Matlab 与C/C++混合编程的问题。本文基于Matlab 6.5和VC6.0 开发环境,在Windows 平台下就它们之间的混合编程问题进行深入研究并举例说明。

  2 Matlab 调用C/C++

  Matlab 调用C/C++的方式主要有两种:利用MEX 技术和调用C/C++动态连接库。

  在Matlab 与C/C++混合编程之前,必须先对Matlab 的编译应用程序mex 和编译器mbuild进行正确的设置[1]:

  对Matlab 编译应用程序mex 的设置:Mex –setup.

  对Matlab 编译器mbuild 的设置:Mbuild –setup.

  2.1 调用C/C++的MEX 文件

  MEX 是Matlab Executable 的缩写,它是一种“可在Matlab 中调用的C(或Fortran)语 言衍生程序”[6]。MEX 文件的使用极为方便,其调用方式与Matlab 的内建函数完全相同,只 需在Matlab 命令提示符下键入MEX 文件名即可。

  一个C/C++的MEX源程序通常包括4个组成部分,其中前3个是必须包含的内容,第4个则根据所实现的功能灵活选用:(1)#include “mex.h”;(2)MEX文件的入口函数mexFunction, MEX文件导出名必须为mexFunction函数;(3)mxArray;(4)API函数

  通过简单的例子说明C/C++的MEX 源程序编写和调用过程:

  #include "mex.h"

  void timeSTwo(double y[], double x[])

  { y[0] = 2.0*x[0]; }

  void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )

  { double *x,*y; int mrows,ncols;

  if(nrhs!=1) mexErrMsgTxt("One input required.");

  else if(nlhs>1) mexErrMsgTxt("Too many output arguments");

  mrows = mxGetM(prhs[0]);ncols = mxGetN(prhs[0]);

  if( !mxIsDouble(prhs[0])||mxIsComplex(prhs[0])||!(mrows==1 && ncols==1))

  mexErrMsgTxt("Input must be a noncomplex scalar double.");

  plhs[0]=mxCreateDoubleMatrix(mrows,ncols, mxREAL);

  x=mxGetPr(prhs[0]); y=mxGetPr(plhs[0]); timestwo(y,x); }

  用指令mex timestwo.c 编译此文件,然后在MATLAB 命令行下调用生成的MEX 文件即可。

  2.2 调用C/C++动态连接库

  Matlab 提供对动态连接库DLL 文件的接口[7]。利用该接口,可在Matlab 中调用动态连 接库导出的函数。Matlab 对DLL 的接口支持各种语言编写的DLL 文件。在调用DLL 文件之 前,需要准备函数定义的头文件。对于C/C++语言开发的DLL 文件,可使用源程序中相应的 头文件;而对于其他语言开发的DLL,则要手工准备等效的C 语言函数定义头文件。

  在Matlab 中利用动态连接库接口技术通常需要完成以下4 个步骤:

  (1)打开动态连接库文件;(2)为调用函数准备数据;(3)调用动态连接库文件中导出的 函数;(4)关闭动态连接库文件。

  为了实现以上步骤,用到的Matlab 函数有:loadlibrary,loadlibrary,calllib, libfunctions,lipointer,libstruct,libisloaded。下面举例说明Matlab 调用C/C++动态 连接库的方法和步骤:

  a.在VC 环境下,新建工程->win32 动态连接库->工程名Test1->empty 工程->完成;

  b.新建->C++源文件->添加a.cpp,内容为: #include "a.h"

  _declspec(dllexport) int add(int a, int b) { return a+b; }

  c.新建->C/C++头文件->添加a.h,内容为: _declspec(dllexport) int add(int a,intb);然后编译生成Test1.dll 动态连接库文件,将Test1.dll 和a.h 拷到Matlab 工作目录下。

  d.在Matlab 命令行下,调用Test.dll:>>loadlibrary(‘Test1’,’a.h’); >>x=7;

  >>y=8; >>calllib(‘Test1’,‘add’,x,y); Ans=15 >>unloadlibrary(‘Test1’).

  调用DLL 动态连接库的方法,为Matlab 重用工程实践中积累的大量实用C/C++代码提供了一种简洁方便的方法。与调用MEX 文件相比,该方法更加简便实用。

  3 C/C++调用Matlab

  在工程实践中,C/C++调用Matlab 的方法主要有调用Matlab 计算引擎、包含m 文件转 换的C/C++文件,以及调用m 文件生成的DLL 文件。

  3.1 利用Matlab 计算引擎

  Matlab 的引擎库为用户提供了一些接口函数,利用这些接口函数,用户在自己的程序 中以计算引擎方式调用Matlab 文件。该方法采用客户机/服务器的方式,利用Matlab 引擎 将Matlab 和C/C++联系起来。在实际应用中,C/C++程序为客户机,Matlab 作为本地服务器。

  C/C++程序向Matlab 计算引擎传递命令和数据信息,并从Matlab 计算引擎接收数据信息[2]。

  Matlab 提供了以下几个C 语言计算引擎访问函数供用户使用[8]:engOpen,engClose, engGetVariable,engPutVariable,engEvalString,engOutputBuffer,engOpenSingleUse, engGetVisible,engSetVisible。

  下面以C 语言编写的、调用Matlab 引擎计算方程x3 ?2x+5=0根的源程序example2.c 为 例,说明C/C++调用Matlab 计算引擎编程的原理和步骤:

  #include #include

  #include #include "engine.h"

  int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,

  LPSTR lpszCmdLine, int nCmdShow)

  { Engine *ep; mxArray *P=NULL,*r=NULL;

  char buffer[301]; double poly[4]={1,0,-2,5};

  if (!(ep=engOpen(NULL)))

  {fprintf(stderr,"nCan't start MATLAB enginen"); return EXIT_FAILURE;}

  P=mxCreateDoubleMatrix(1,4,mxREAL); mxSetClassName(P,"p");

  memcpy((char *)mxGetPr(P),(char *)poly, 4*sizeof(double));

  engPutVariable(ep,P); engOutputBuffer(ep,buffer,300);

  engEvalString(ep,"disp(['多项式',poly2str(p,'x'),'的根']),r=roots(p)");

  MESSageBox(NULL,buffer,"example2 展示MATLAB 引擎的应用",MB_OK);

  engClose(ep); mxDestroyArray(P); return EXIT_SUCCESS; }

  在Matlab 下运行example2.exe: mex -f example2.c。运行结果如图1 所示:


  利用计算引擎调用Matlab的特点是:节省大量的系统资源,应用程序整体性能较好,但 不能脱离Matlab的环境运行,且运行速度较慢,但在一些特别的应用[9](例如需要进行三维 图形显示)时可考虑使用。

  3.2 利用mcc 编译器生成的cpp 和hpp 文件

  Matlab自带的C++Complier--mcc,能将m文件转换为C/C++代码。因此,它为C/C++程序调用m文件提供了另一种便捷的方法。下面举例说明相应步骤:

  a.新建example3.m:function y=exmaple3(n) y=0; for i=1:n y=y+i;end

  保存后在命令窗口中输入:mcc -t -L Cpp -h example3.

  则在工作目录下生成example3.cpp 和example3.hpp 两个文件。

  b.在VC 中新建一个基于对话框的MFC 应用程序Test2,添加一个按钮,并添加按钮响应函数,函数内容见f 步。将上面生成的两个文件拷贝到VC 工程的Test2 目录下。

  c.在VC 中选择:工程->设置,选择属性表Link 选项,下拉菜单中选择Input,在对象 / 库模块中加入lIBMmfile.lib libmatlb.lib libmx.lib libmat.lib libmatpm.lib sgl.lib libmwsglm.lib libmwservices.lib , 注意用空格分开; 而在忽略库中加入 msvcrt.lib;

  d.选择属性表C/C++选项,下拉菜单选General,在预处理程序定义中保留原来有的内 容,并添加MSVC,IBMPC,MSWIND,并用逗号隔开。选择下拉菜单的Precompiled Headers 选 项,在“自动使用预补偿页眉”中添加stdafx.h,然后确定。

  e. 选择: 工具-> 选项, 属性页选择“ 目录” , 在include files 加入: C:MATLAB6p5p1externinclude , C:MATLAB6p5p1externincludecpp ; 然后在 Library files 里面加入: C:MATLAB6p5p1binwin32 , C:MATLAB6p5p1extern libwin32microsoftmsvc60;注意根据用户的Matlab 安装位置,修改相应目录。

  f.在响应函数中添加头文件:#include "matlab.hpp" #include "example3.hpp" 函数响应代码为:

  int i; mwArray n; n=10; n=example3(n); i=n.ExtractScalar(1);

  CString str; str.Format("example3 的返回值是:%d",i); AfxMessageBox(str);

  g. 编译,连接,执行,结果如图2 所示。


  3.3 利用mcc 编译器生成的的DLL 文件

  Matlab的C++ Complier不仅能够将Matlab的m文件转换为C/C++的源代码,还能产生完全 脱离Matlab运行环境的独立可执行DLL程序。从而可以在C/C++程序中,通过调用DLL实现对 Matlab代码的调用。下面通过一个简单的例子说明C/C++调用m文件生成的DLL:

  a.建立m文件example4.m: function result=example4(para)

  x=[1 para 3]; y=[1 3 1]; plot(x,y); result=para*2; end.然后在命令窗口中输入:

  mcc -t -W libhg:example4 -T link:lib -h libmmfile.mlib libmwsglm.mlib example4则在工作目录下会生成example4 .dll、example4 .lib和example4 .h三个文件。

  b.在VC中新建一个基于对话框的应用程序Test3,然后添加一个按钮及按钮响应函数,函数内容见d步,再将生成的3个文件拷贝到Test2工程目录下。

  c.VC编译环境的设置如同3.2节c、d步;

  d.在按钮函数文件添加如下的头文件:#include "example4 .h" ,函数响应代码为:

  mxArray* para=mxCreateDoubleScalar(2); mxArray* result; example4Initialize();

  result=mlfExample4(para); CString str;

  str.Format("%f",mxGetScalar(result)); AfxMessageBox(str);

  e.编译,连接,执行,结果如图3所示。


  利用mcc 编译器生成的DLL 动态连接库文件,只需在C/C++编译环境中将其包含进来, 调用导出函数即可实现原m 文件的功能,极大地方便了用户的代码设计。

  4 结束语

  本文从Matlab 调用C/C++代码和C/C+调用m 文件两方面,详细地研究了Matlab 与C/C++ 混合编程技术。对于Matlab 调用C/C++代码,给出了常用的MEX 技术和调用C/C++动态连接 库的方法,并对它们进行比较。针对用户在实际中经常遇到的C/C++调用Matlab 问题,通过研究给出了常用的三种方法及其特点:利用Matlab 计算引擎的方法,混合编程后的可执 行程序脱离不了Matlab 的运行环境,运行速度很慢;利用mcc 编译器将m 文件转化为C/C++ 文件的方法,虽然能独立于Matlab 运行环境,可在C/C++环境中包含生成的文件非常繁琐; 但是m 文件生成的DLL 为用户提供了一种简洁方便的C/C++调用Matlab 代码的方法。除 Matlab 自带的mcc 外,Matcom 也能将M 文件编译为C/C++文件和DLL 文件[2][8],但混合编程 原理一样,在此省略。

关键字:Matlab  混合编程 引用地址:Matlab与C/C++混合编程接口及应用

上一篇:基于PCIe总线的超高速信号采集卡的设计
下一篇:FPGA并行数字序列传输与接口技术应用

推荐阅读最新更新时间:2024-05-02 21:40

基于MATLAB的单相桥式整流电路研究
   1 引言   整流电路(Rectifier)尤其是单相桥式可控整流电路是电力电子技术中最为重要,也是应用得最为广泛的电路,不仅应用于一般工业,也广泛应用于交通运输、电力系统、通信系统、能源系统等其他领域。因此对单相桥式可控整流电路的相关参数和不同性质负载的工作情况进行对比分析与研究具有很强的现实意义,不仅是电力电子电路理论学习的重要一环,而且对工程实践的实际应用具有预测和指导作用。    2 单相桥式半控整流电路   图1中VT1和VT2为触发脉冲相位互差180◦的晶闸管,VD1和VD2为整流二极管,由这四个器件组成单相桥式半控整流电路。电阻R和电感L为负载,若假定电感L足够大,即ωL≥R,由于电感中电流不能突变
[电源管理]
声卡和Matlab的虚拟信号发生器的工作原理
声卡从话筒中获取声音模拟信号,通过模数转换器(ADC),将声波振幅信号采样转换成一串数字信号,存储到计算机中。重放时,这些数字信号送到数模转换器(DAC),以同样的采样速度还原为模拟波形,放大后送到扬声器发声,这一技术称为脉冲编码调制技术(PCM)。作为多媒体计算机系统中最基本最常用的硬件之一,其技术已经发展成熟,他同时具有A/D和D/A转换功能,经济方便,目前已经被广泛应用于数据采集和虚拟仪器系统的设计[1,2]。Matlab是一个数据分析和处理功能十分强大的工程实用软件,他的数据采集工具箱(dataacquisitiontoolbox)为实现数据的输入和输出提供了十分方便的函数和命令,利用这些函数和命令可以很容易地实现对外部
[测试测量]
MATLAB和SIMULINK助力NASA回归到载人航天飞行
利用基于模型的设计, 猎户座导航、制导和控制系统成功地完成了深空试验飞行。 中国北京 2015 年 3 月 30 日 MathWorks今日详细报告了它对于成功完成美国宇航局 (NASA) 猎户座飞船试验飞行的贡献。此次飞行于 2014 年 12 月 5 日结束,标志着 40 多年来为宇航员设计的所有飞船在太空中所飞行的最远距离。猎户座这次的里程碑事件被认为是 NASA 在使用载人飞船探索深空飞行并抵达火星的研究工作中迈出了重要的一步。船载导航、制导和控制 (GN&C) 系统让猎户座利用 GPS 和惯性传感器从发射到着陆期间成功进行了导航。这些 GN&C 算法是利用 MATLAB 和 Simulink 自动生成
[嵌入式]
<font color='red'>MATLAB</font>和SIMULINK助力NASA回归到载人航天飞行
MathWorks 推出 2018b 版本的 MATLAB 和 Simulink
MathWorks 宣布,推出 2018b 版本的 MATLAB 和 Simulink。该版本包含重要的深度学习增强功能,以及各个产品系列中的新功能和Bug修复。新的 Deep Learning Toolbox 取代了 Neural Network Toolbox,为工程师和科学家提供了用于设计和实现深度神经网络的框架。现在,图像处理、计算机视觉、信号处理和系统工程师可以使用 MATLAB 更轻松地设计复杂的网络架构,并改进其深度学习模型的性能。 MathWorks 最近加入了 ONNX 社区,表明其对互操作性的支持,从而实现 MATLAB 用户与其他深度学习框架用户之间的协作。使用 R2018b 中的新 ONNX 转换器,工
[网络通信]
高频斩波式串级调速系统的建模研究
  1 引言   串级调速是一种经典的高效节能调速方案 ,而高频斩波串级调速系统是在传统串级调速理论基础上,应用现代电机技术、电力电子技术和计算机控制技术的先进成果而产生的新一代高效调速技术。该技术以控制转子低电压回路进而控制高压电机,以变流转差功率进而控制大功率电机,并以高频斩波器实现PWM脉宽调制替代传统串级调速系统的逆变角调节,具有控制容量小、控制电压低,调速性能优良和节能效率高、谐波功率小,装置尺寸小,运行条件宽松等优点,在高压大容量电机节能调速上具有突出的优势 。   在实际工程设计中,常需进行计算机仿真研究,以获得指导性结论或对工程计算参数进行验证。在仿真技术中,常采用的数学模型形式有:传递函数、开关函数或状态方程
[工业控制]
Matlab在FIR数字滤波器中的应
提出 FIR数字滤波器 的设计方案,并基于Matlab实现滤波仿真。通过使用Matlab信号处理工具箱提供的函数,选择适当的窗函数编写程序,其中窗函数按照实际信号的处理需求,参数折中选择。实验获得了比较理想的滤波器特性,可以实现较好的滤波作用。而且在实际应用中只需按需求修改滤波器参数,并结合程序的相应改动,即可实现不同功能的滤波器。另外,介绍了利用FDATool设计滤波器的方法,简单修改参数即可实现多种滤波器。   1 数字滤波器及设计方案   应用数字滤波器处理模拟信号时,首先要对输入模拟信号进行限带、抽样和模/数转换,数字滤波器输入信号的抽样率应大于被处理信号带竟的两倍,其频率响应具有以抽样频率为间隔的周期重复特性
[模拟电子]
<font color='red'>Matlab</font>在FIR数字滤波器中的应
应用TEXTl0和MATLAB进行复杂数字系统仿真
摘要:在基于FPGA的复杂数字系统的仿真测试中,设计者常常面临各种挑战。以数字图像处理系统的仿真为例。如果采用完备性仿真测试方法,那么测试矢量的数量将是非常巨大的;如果采用常规方法.不仅效率不高.而且可能无法达到仿真测试的目的。针对这个难题,提出一种进行仿真测试的新方法.该方法应用TEXTIO和MATLAB来辅助仿真测试过程,使问题得到较好的解决。以电视图像实时多目标捕获单元的仿真测试为例。全面、细致地讨论这种新方法。 关 键 词:TEXTIO;MATLAB;TestBench;仿真;测试激励 中图分类号:TN707 文献标识码:A 文章编号:。1006—6977(2006)01—0004—04 1 引言 在对复杂数字系统进行
[半导体设计/制造]
TMS320C54XDSP混合编程的方法研究
    摘要: 提出并分析了在考虑程序代码效率、执行效率和程序的可读性及可移植性的情况下,对于TMS320C54X系列,采用C语言和汇编语言混合编程的优点;详细阐述了混合编程方法的特点、应遵循的规则和详细接口规范;给出了程序设计实例。     关键词: 数字信号处理(DSP) TMS320C54X 混合编程 数字信号处理技术是一门涉及许多学科的新技术,广泛应用于军事、工业、航空、航天等诸多领域。数字信号处理技术由于其运行量大和实现算法复杂,通常采用专用的DSP芯片来实现。美国TI公司的TMS320C54X系列芯片是为实现低功耗和高性能而专门设计的定点DSP芯片。 TMS320C54X的主要特点包括:高运算速度
[应用]
小广播
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved