1 引言

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

C/C++语言是目前最为流行的高级程序设计语言之一。它可对操作系统和应用程序以 及硬件进行直接操作,用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进行正确的设置:

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

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

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

MEX 是Matlab Executable 的缩写,它是一种“可在Matlab 中调用的C(或Fortran)语 言衍生程序”。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 文件的接口。利用该接口,可在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 计算引擎接收数据信息。

Matlab 提供了以下几个C 语言计算引擎访问函数供用户使用: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={1,0,-2,5};

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

{fprintf(stderr,“\nCan‘t start MATLAB engine\n”); 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的环境运行,且运行速度较慢,但在一些特别的应用(例如需要进行三维 图形显示)时可考虑使用。

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:\MATLAB6p5p1\extern\include , C:\MATLAB6p5p1\extern\include\cpp ; 然后在 Library files 里面加入: C:\MATLAB6p5p1\bin\win32 , C:\MATLAB6p5p1\extern\ lib\win32\microsoft\msvc60;注意根据用户的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 文件,但混合编程 原理一样,在此省略。

来源;电子工程网

怎么把dll库写成MATLAB接口,如何在Matlab中应用动态连接库接口技术相关推荐

  1. 在VB 中调用动态连接库

    在VB 中调用动态连接库   2001-11-08· · ··yesky 1 2 3 4 5 6 7 8  下一页 作为一种简单易用的Windows开发环境,Visual Basic从一推出就受到了广 ...

  2. CorelDRAWX4的VBA插件开发(三十一)使用C++制作动态连接库DLL辅助VBA构键强大功能-(5)在VBA中动态调用DLL文件

    我们先来看一下动态调用的截图 先上代码 '静态调用 Public Declare Function wodedll Lib "E:\VS-DLL\conglingkaishi\Debug\C ...

  3. CorelDRAWX4的VBA插件开发(二十七)使用C++制作动态连接库DLL辅助VBA构键强大功能-(1)前言和准备工作

    我们在使用VBA的时候会很多的局限性,包括调用库和递归函数,对指针结构体和类都不友好,对时间复杂度和空间复杂度都优化得不够,换言之VB就不是从性能出发的语言,所以难免力不从心 所以这里用C++为VBA ...

  4. MATLAB的仿真工具箱Simulink中常用的模块库总结

    MATLAB的仿真工具箱Simulink中常用的模块库 Simulink中常用的模块库主要包括如下几种. (1)信宿(Sinks)模块库:包括显示或将输出回写的模块. Display 显示输入的值: ...

  5. Android中将TableRow写成自定义控件后,在LayoutTable中的stretchColumns属性没有生效

    Android中将TableRow写成自定义控件后,在LayoutTable中的stretchColumns属性没有生效 第一行是原本的样子,也是理想中的样子. 第二行是将第一列的TableRow写成 ...

  6. QT动态连接库的编写

    1.QT动态链接库的编写流程 1.1 首先在Qt Creator中创建一个动态连接库Matrix,添加类名,生成一个类(matrix.h和matrix.cpp)和一个matrix_global.h的文 ...

  7. [转]Linux下的动态连接库及其实现机制

    摘 要:本文介绍了动态连接库的优点,详细阐述了x86体系结构上Linux系统的编译器 .连接器.加载器如何使用多种重定位方式来实现该功能 关键词:动态连接库:Linux:重定位 The Impleme ...

  8. 动态连接库和静态链接库

    文章出处:http://www.cnblogs.com/gaoyihan/p/4723332.html 本文参考了以下博客:      1. http://blog.csdn.net/gamecrea ...

  9. c++与fortran混合语言编程中动态链接库的调用,[转载]C++与Fortran混合语言编程中动态连接库的调用...

    摘 要:介绍了C++和Fortran 90混合语言编程中,在C++中调用Fortran动态连接库(DLL,Dynamic Link Library)的方法以及参量传递.函数调用等的方法. 关键词:混合 ...

最新文章

  1. AppStore审核2.1被拒大礼包过审经历
  2. NR 5G 运营发布
  3. MySQL数据库优化总结
  4. 路由策略原理及配置请查收......
  5. java多线程模拟loadrunner进行压测
  6. 断网python第三方库安装_Python离线断网情况下安装numpy、pandas和matplotlib等常用第三方包...
  7. java.io.NotSerializableException: com.codahale.metrics.MetricRegistry
  8. fiddler模拟不同的IP
  9. mock SpringMVC 测试控制器方法
  10. python爬虫——与不断变化的页面死磕和更新换代(3)
  11. 相亲交友小程序开发方案及源码
  12. 多张pdf怎么合成一张?pdf快速合并法
  13. 使用fiddler+itunes来做到下载APP在AppStore中的历史版本 注意事项
  14. Invisible Backdoor Attack with Sample-Specific Triggers
  15. adf的主要功能之一是_复印机ADF是什么意思
  16. html的progress 怎么改变默认样式
  17. python 读取pdf cid_python使用pdfminer解析pdf文件的方法示例
  18. B 吃雪糕(科林明伦杯)
  19. R语言学习day2丨三大法宝:判断、循环、函数
  20. 解决es查询异常:lasticsearch exception [type=illegal_argument_exception, reason=Can‘t load fielddata on....

热门文章

  1. java字符串与基本数据_java --字符串与基本数据类型之间的转换
  2. windows共享linux的某一文件夹
  3. 怎么导入mysql示例_MySQL命令行导出导入数据库实例详解
  4. python数据库教程_python教程:数据库
  5. seaborn使用jointplot函数为散点图添加边缘图、添加回归线、为边缘直方图添加密度曲线、自定义边缘直方图的色彩(Change Color of Marginal Histogram Plot
  6. R语言使用ggpubr包的ggarrange函数组合多张结论图(垂直组合+水平组合)并对图像进行顺序编码A、B、C,,,
  7. R语言ggplot2可视化时间序列数据并添加稳定趋势线识别数据的稳定趋势
  8. R语言使用plotly绘制3D散点图实战
  9. R语言构建xgboost模型:模型的保存(xgb.save)和加载(xgb.load)、或者保存为R二进制文件(xgb.save.raw R binary vector)
  10. R语言基于glmnet构建分类模型并可视化特征系数(coefficient)以及L1正则化系数(lambda)实战