MATLAB与C的混合编程

更新时间:2024-05-25 16:16:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

编号

学士学位论文

MATLAB与C的混合编程

学生姓名: 学 号: 系 部: 专 业: 电子信息科学与技术 年 级: 指导教师: 完成日期: 年 月 日

学 士 学 位 论 文

BACHELOR ’S THESIS 中文摘要

对MATLAB与C语言进行混合编程的常用方法(MAT文件、MEX文件、MATLAB计算引擎、MATLAB编译器、MCC和MATCOM)进行了介绍,分析了其实现方法和各自的利弊。通过MAT文件实现与其它编程环境的数据交换,通过MEX文件实现在MATLAB环境中调用其它语言编写的程序,通过MATLAB引擎实现其它编程环境中使用MATLAB的计算功能,通过MATCOM技术将MATLAB的源代码译成同等功能的C源代码。并用实例对MEX文件实现方式进行了较详细的论述。通过混合编程,利用了C语言高效的特点,在发挥MATLAB强大的计算功能的同时,又弥补其执行速度慢的缺点。

关键词:MATLAB; C; MAT文件; MEX文件; MATLAB计算引擎;MATLAB编译器; MCC和MATCOM; 混合编程

Mixed programming technology for MATLAB with

C

Abstract

On MATLAB and C language common methods of mixing programming (MAT files, documents and MATLAB calculation engine MEX MATLAB, the compiler, MCC and MATCOM) are introduced, analyzes its implementation method and their respective advantages and disadvantages. Through the MAT files realization and other programming environment, through the data exchange MEX files in the MATLAB environment of realizing invoke other language program, through On

I

学 士 学 位 论 文

BACHELOR ’S THESIS MATLAB and C language common methods of mixing programming (MAT files, documents and MATLAB calculation engine MEX MATLAB, the compiler, MCC and MATCOM) are introduced, analyzes its implementation method and their respective advantages and disadvantages. Through the MAT files realization and other programming environment, through the data exchange MEX files in the MATLAB environment of realizing invoke other language program, through Key words:MATLAB; C; MAT files; MEX files; MATLAB calculation engine ; MATLAB Compiler; MCC and MATCOM; Mixed programming technology

II

学 士 学 位 论 文

BACHELOR ’S THESIS 目 录

中文摘要 .......................................................................................................................I ABSTRACT ..................................................................................................................I 引言 .............................................................................................................................. 1 1. MATLAB .................................................................................................................. 1 1.1 MATLAB简介 ................................................................................................. 1 1.2 MATLAB的语言特点 ..................................................................................... 1 2. C 语言...................................................................................................................... 3 2.1 C语言简介 ....................................................................................................... 3 2.2 C语言特点 ....................................................................................................... 4 3. 混合编程的实现方式 ............................................................................................. 4 3.1 MAT文件........................................................................................................ 5 3.2 MEX文件 ....................................................................................................... 8 3.3 MATLAB计算引擎...................................................................................... 11 3.4 MATLAB编译器.......................................................................................... 13 3.5 MCC ................................................................................................................ 13 3.6 MATCOM ....................................................................................................... 16 4. C语言MEX文件的实现 ...................................................................................... 17 4.1 C语言MEX文件的编写............................................................................. 17 4.2 编译器的配置................................................................................................. 20 4.3 C语言MEX文件的编译............................................................................. 20 4.4 举例说明C的 MEX源程序的编写和调用过程 ......................................... 20 5. 结语 ....................................................................................................................... 24 参考文献 .................................................................................................................... 26

III

学 士 学 位 论 文

BACHELOR ’S THESIS 致 谢 .......................................................................................................................... 28

IV

学 士 学 位 论 文

BACHELOR ’S THESIS 引言

MATLAB语言具有功能强大、开发效率高等诸多优点,已在工程实际中得到广泛应用,但是与C语言相比,其执行效率较低,特别是当程序中含有大量循环语句(例如迭代计算)时,MATLAB就有些力不从心,速度很慢,而运用擅长数值计算语言进行编程,气运行效率高。一方面,如果放弃MATLAB强大功能和数量众多的应用工具箱,无疑是自愿的极大浪费。另一方面,针对工程实际,人们用C语言已编写了大量实用程序,如果将其重新改写成M文件一直到MATLAB环境中,不仅要花费大量的时间和精力,而且有时还降低了其运行效率。可否将两者优势互补呢?混合编程就是其有效地解决途径。

1. MATLAB

1.1 MATLAB简介

MATLAB是一种以矩阵为基本数据对象的科学计算语言,它提供了功能齐全的函数库和各种工具箱,具有强大的科学分析、数值计算、图形绘制等功能。MATLAB是当前应用最为广泛的数学软件,利用这一完整的数学平台,用户可以快速实现十分复杂的功能,极大的提高了工程分析计算的效率。但与其他高级程序相比,MATLAB程序是一种解释执行程序,不用编译等预处理,程序运行速度较慢。[1]

1.2 MATLAB的语言特点

一种语言之所以能如此迅速地普及,显示出如此旺盛的生命力,是由于它有着不同于其他语言的特点,正如同C等高级语言使人们摆脱了需要直接对计算机硬件资源进行操作一样,被称作为第四代计算机语言的MATLAB,利用其丰富的函数资源,使编程人员从繁琐的程序代码中解放出来。MATLAB最突出的特点就是简洁。MATLAB用更直观的,符合人们思维习惯的代码,代替了C

1

学 士 学 位 论 文

BACHELOR ’S THESIS 和语言的冗长代码。MATLAB给用户带来的是最直观,最简洁的程序开发环境。以下简单介绍一下MATLAB的主要特点。

1)语言简洁紧凑,使用方便灵活,库函数极其丰富。MATLAB程序书写形式自由,利用起丰富的库函数避开繁杂的子程序编程任务,压缩了一切不必要的编程工作。由于库函数都由本领域的专家编写,用户不必担心函数的可靠性。可以说,用MATLAB进行科技开发是站在专家的肩膀上。

具有C等高级语言知识的读者可能已经注意到,如果用C语言去编写程序,尤其当涉及矩阵运算和画图时,编程会很麻烦。例如,如果用户想求解一个线性代数方程,就得编写一个程序块读入数据,然后再使用一种求解线性方程的算法(例如追赶法)编写一个程序块来求解方程,最后再输出计算结果。在求解过程中,最麻烦的要算第二部分。解线性方程的麻烦在于要对矩阵的元素作循环,选择稳定的算法以及代码的调试动不容易。即使有部分源代码,用户也会感到麻烦,且不能保证运算的稳定性。解线性方程的程序用C这样的高级语言编写,至少需要四百多行,调试这种几百行的计算程序可以说很困难。以下用MATLAB编写以上两个小程序的具体过程。

MATLAB求解下列方程,并求解矩阵A的特征值。 Ax=b,其中:

A= 32 13 45 67 23 79 85 12 43 23 54 65 98 34 71 35 b= 1 2 3 4

解为:x=A\\b;设A的特征值组成的向量e,e=eig(A)。可见,MATLAB的程序极其简短。更为难能可贵的是,MATLAB甚至具有一定的智能水平,比如上面的解方程,MATLAB会根据矩阵的特性选择方程的求解方法,所以用户根本不用怀疑MATLAB的准确性。

2)运算符丰富。由于MATLAB是用C语言编写的,MATLAB提供了和

2

学 士 学 位 论 文

BACHELOR ’S THESIS C语言几乎一样多的运算符,灵活使用MATLAB的运算符将使程序变得极为简短。

3)MATLAB既具有结构化的控制语句(如for循环,while循环,break语句和if语句),又有面向对象编程的特性。

4)程序限制不严格,程序设计自由度大。例如,在MATLAB里,用户无需对矩阵预定义就可使用。

5)程序的可移植性很好,基本上不做修改就可以在各种型号的计算机和操作系统上运行。

6)MATLAB的图形功能强大。在C语言里,绘图都很不容易,但在MATLAB里,数据的可视化非常简单。MATLAB还具有较强的编辑图形界面的能力。

7)MATLAB的缺点是,它和其他高级程序相比,程序的执行速度较慢。由于MATLAB的程序不用编译等预处理,也不生成可执行文件,程序为解释执行,所以速度较慢。

8)功能强大的工具箱是MATLAB的另一特色。MATLAB包含两个部分:核心部分和各种可选的工具箱。核心部分中有数百个核心内部函数。其工具箱又分为两类:功能性工具箱和学科性工具箱。功能性工具箱主要用来扩充其符号计算功能,图示建模仿真功能,文字处理功能以及与硬件实时交互功能。功能性工具箱用于多种学科。而学科性工具箱是专业性比较强的,如control,toolbox,signl proceessing toolbox,commumnication toolbox等。这些工具箱都是由该领域内学术水平很高的专家编写的,所以用户无需编写自己学科范围内的基础程序,而直接进行高,精,尖的研究。

9)源程序的开放性。开放性也许是MATLAB最受人们欢迎的特点。除内部函数以外,所有MATLAB的核心文件和工具箱文件都是可读可改的源文件,用户可通过对源文件的修改以及加入自己的文件构成新的工具箱。

2. C 语言

2.1 C语言简介

C语言功能丰富、表达能力强、使用灵活方便、应用面广、目标程序效率高、可移植性好,既具有高级语言的优点,又具有许多低级语言的特点,是目

3

学 士 学 位 论 文

BACHELOR ’S THESIS 前应用最广的编程语言。它对操作系统和应用程序以及硬件进行直接操作,一些大型应用软件如MATLAB就是用C语言开发的。[2]

2.2 C语言特点

C语言之所以能迅速崛起,并成为最受欢迎的程序设计语言之一,是因为它有许多优于其它语言的特点。C语言具有下列特点:

1)C语言功能齐全。C语言的数据类型有:整型、实型、字符型、无符号整型、数组类型、指针类型、结构体类型、共用体类型、枚举型等。C语言运算符丰富,表达式类型有:赋值表达式、关系表达式、算术表达式、逻辑表达式、条件表达式、逗号表达式以及为运算等。

2)C语言简洁、紧凑,使用方便、灵活。C语言的一个语句可完成多个操作。一个表达式也可以完成多个操作。书写简练,源程序短,因而输入程序工作量小。

3)C是面向结构化程序设计的语言。结构化语言的显著特点是代码、数据的模块化,C程序是以函数的形式提供给用户的,这些函数调用方便。C语言具有多种条件语句、循环控制程序流向(如if/else语句,switch语句,while语句,do/while语句,for语句,break语句,continue语句等)。从而使程序完全结构化。

4)C是中级语言。他把高级语言的基本结构和语句与低级语言的实用性结合起来。C语言可以像汇编语言一样对位、字节好地址进行操作,实现汇编语言的大部分功能,可直接对硬件进行编程。用C语言加上一些汇编语言子程序编程,更能显示C语言的优势。C语言源程序编译后代码短、执行效率高。

5)C语言适用范围大。C语言还有一个突出的优点就是适合于多种操作系统,如DOS、Windows、UNIX,也适用于多种机型。源程序代码可移植性好。

3. 混合编程的实现方式

正式考虑到上面这些原由,MATLAB系统提供了其应用程序接口(Application Program Interface)来解决这些问题。API主要包括3部分:MEX

4

学 士 学 位 论 文

BACHELOR ’S THESIS 文件—外部程序调用接口,用来在MATLAB环境下调用C语言编写的程序;MAT文件应用程序—数据输入输出接口,用于MATLAB系统与外部环境之间互传数据;计算引擎函数库—MATLAB处于后台作为一个计算引擎,与其它应用程序建立客户机/服务器关系,在其他其应用程序中调用。

3.1 MAT文件

MAT文件是MATLAB使用的一种特有的二进制数据文件。MAT文件可以包含一个或者多个MATLAB变量。在MAT文件中不仅保存各变量数据本身,而且同时保存变量名以及数据类型等。所以在MATLAB中载入某个MAT文件后,可以在当前MATLAB工作空间完全再现当初保存该MAT文件时的那些变量。这是其他文件格式所不能的。同样,用户也可以使用MAT文件从MATLAB环境中导出数据。MAT文件提供了一种更简便的机制在不同操作平台之间移动MATLAB数据。

C程序中有两种方式可以读取MAT文件数据。一种是利用MATLAB提供的有关MAT文件的编程接口函数。MATLAB的库函数中包含了MAT文件接口函数库,其中有各种对MAT文件进行读写的函数,都是以mat开头的函数。

另一种在C程序中读写MAT文件的方法是根据MAT文件函数结构,以二进制格式在读取文件内容,然后解析文件内容,从而获得文件中保存的MATLAB数据。因为MAT文件格式是公开的,用户只要在找到安装路径下的一个名为matfile format.pdf的文件,就可以详细了解MAT文件结构,从而在C程序以二进制格式在读取文件内容,解析以后得到文件中保存的数据。[3][4]

简单举例:

· 获取一个MAT文件中第一个矩阵的信息 · 获取一个MAT文件中第一个矩阵的信息 typedef struct { char szFileName[256]; MATFile* pMatFile; mxArray* pArray; char szArrayName[64];

5

学 士 学 位 论 文

BACHELOR ’S THESIS plhs[0]=mxCreateDoubleMatrix(x,x,mxREAL); n=mxGetM(plhs[0]); y=mxGetPr(plhs[0]); hilb(y,n); }

该程序是一个C语言程序,它也实现了建立Hilbert矩阵的功能。MATLAB命令窗口输入以下命令:mex Matlab_1.cpp,即可编译成功。进入该文件夹,会发现多了两个文件:Matlab_1.asv和Matlab_1.dll,其中Matlab_1.dll即是MEX文件。运行下面程序:

tic

a=Matlab_1(1000); toc

elapsed_time = 0.0470

由上面看出,同样功能的MEX文件比m文件快得多。

3.3 MATLAB计算引擎

MATLAB引擎函数库是MATLAB提供的一系列程序的集合,它允许用户在自己的应用程序中对MATLAB函数进行调用,将MATLAB作为一个计算引擎使用,让其在后台运行,这样可以简化前台用户程序的设计任务。[5]

当用户使用MATLAB引擎时,相当于在后台启动了一个MATLAB进程。MATLAB引擎函数库在用户程序与MATLAB进程之间起一个桥梁的作用,完成两者的数据交换和命令的传送。

在实际应用中,MATLAB作为Activex的自动化服务器,接受通过引擎传来的数据和指令信息并进行相应的处理,然后将结果经过引擎返回给发送请求的客户机。但这种方式需要MATLAB在后台适时的运行,如果用户没有安装MATLAB,应用程序就无法正常运行,而且应用程序与MATLAB间通过字符流传数据和命令参数,整个算法在MATLAB中执行,从而降低了程序的执行效

11

学 士 学 位 论 文

BACHELOR ’S THESIS 率,故而其实际应用不多。[1][6]

简单举例:

如以下C 代码段可以完成完整的数据交互功能:

Engine * ep; ep = engOpen( 0) ; / / 定义并打开引擎

mxArray * M, * N; / / 定义mxArray 指针用于交互数据 double C[ 500] , D[ 500] ; , , / / C 数组赋初值

M = mxCreateDoubleMatrix ( 1, 500, mxREAL) ; / / 创建 Double 型实阵列

memcpy( ( char * ) mxGetPr (M) , ( char * ) C, 500* sizeof ( double) ) ; / / 将数组C赋至阵列的实部

mxSetName ( M, / MM0) ; / / 设置阵列M 在Matlab Workspace 中对应的变量名

engPutArray( ep, M) ; / / 将阵列M 的内容交互到Matlab Workspace 中的相应变量MM

engEvalString( ep, / s= awgn(MM, 8) ;0 ) ; / / 调用Matlab 函数

N = engGetArray( ep, / s0 ) ; / / 将Matlab Workspace 中的变量s 交互到阵列N 中

memcpy( ( char * ) D, ( char * )mxGetPr (N) , 500* sizeof ( double) ) ; / / 将阵列N 实部赋至数组D

mxDestroyArray(M) ; mxDestroyArray(N) ; / / 释放阵列空间 engClose( ep) ; / / 关闭引擎

这种方法通过引擎函数实现了在C 语言中调用MATLAB函数, 包括ToolBox 函数和作图函数等, 但是不能脱离MATLAB环境而生成独立运行的程序, 所以只适于算法仿真或C程序算法调试过程中使用, 而不适于开发。在C 中调用MATLAB 的ToolBox 函数, 可以大大提高仿真编程效率, 减少重复开发。engEvalString 函数中调用的MATLAB 函数在引擎中仍然是以解释性执行的, 其执行效率并不能提高, 所以调用运算量较大的函数时计算时间仍然很长。

12

学 士 学 位 论 文

BACHELOR ’S THESIS 3.4 MATLAB编译器

MATLAB编译器是一个运行于MATLAB环境的独立工具。MATLAB编译器的主要功能是把M程序转换成C代码,然后在调用外部C编译器把产生的源代码编译、链接成用户指定的格式。MATLAB编译器产生的可执行文件或者组件在运行时只需要一个简化的组成形式运行环境,而并不需要MATLAB本身。这个组件形式的MATLAB运行环境可以很方便地从MATLAB派生并且免费发布。这使MATLAB得应用不再只是局限于程序的原型设计和开发。利用MATLAB编译器,完全能够在MATLAB环境中快速开发,可以直接交付用户使用的应用程序,从而极大的缩短应用程序的开发周期。[7]

简单举例:

首先建立两个.m 函数文件: function a = addmatrix(a1,a2) a = a1 + a2;

figure;imshow(mat2gray(a)); title('加法结果显示'); eturn

保存为addmatrix.m。

function m = multiplymatrix(a1, a2) m = a1 * a2;

figure;imshow(mat2gray(m)); title('乘法结果显示'); return

保存为multiplymatrix.m。

这两个.m函数主要执行加法和乘法运算,并将计算结果以图形方式显示。

3.5

前面介绍的方法都不能脱离MATLAB环境独立运用, 而只是C语言程序与MATLAB系统交互的方法。应用MATLAB提供的MCC 命令和C语言数学函数库,

13

学 士 学 位 论 文

BACHELOR ’S THESIS 可以将MATLAB 中的M 代码源文件翻译成C 语言代码文件, 从而实现在C 程序中调用MATLAB中丰富的数据处理和分析库函数。应用MCC 命令的前提是在MATLAB系统中已经用命令mex - setup 和mbuild - set2up 对编译器进行了配置。C语言数学函数库包含了MATLAB 的Matrix 数学计算核心, 是以mxArray 结构体 为核心构建的。通过MCC 命令可以将M 文件转换为基于C 语言数学函数库的C语言源代码文件。需要注意的是, MCC 命令只能转换MATLAB 函数文件,而不能转换脚本文件, 所以脚本类型的M 文件应该先改写为函数类型的M 文件。将转换后的C 语言源文件加入C 工程中, 最终可以编译成脱离MATLAB 环境独立运行的可执行文件。[8]由MCC 转换的C 源文件代码冗余度较大, 在将其加入C 工程时可以将源文件全部加入, 也可以只将其中有用的代码拷贝到自己的程序中。因为这些代码还是以mxArray结构体或mwArray 类为基础的, 所以在编译调试过程中需要有libmmfile . lib、libmatlb. lib、libmx. lib、libmat. lib 静态库文件的支持。由MCC 命令转换后的C 代码冗余度大、可读性不强, 而且速度上仍然比正常编写的C程序慢, 不过由此换来的高开发效率和可靠性往往是值得的。[10][13]

简单举例:

test. m 实现的是两个矩阵的加和减: function[ a, b] = test( x, y) a= x+ y; b= x- y;

利用mcc-t-L Cpp test. m 命令生成test. hpp 和test. cpp 文件。头文件test. hpp 的内容如下

/ /

/ / MATLAB Compiler: 2. 2 / / Date: Tue Jan 15 08: 17: 19 2002 / / Arguments: “- B”“macro default”“- O” “all”“- O”“fold scalar mxarrays: on” / / “- O”“fold non scalar mxarrays: on” “- O”“optimize integer for loops: on”“- O” / / “array indexing: on ”“- O”“optimize

14

学 士 学 位 论 文

BACHELOR ’S THESIS conditionals: on”“- t”“- L”“Cpp”“test. m” / /

# ifndef test hpp # define test hpp 1 # include “libmatlb. hpp”

extern void InitializeModule test( ) ; extern void TerminateModule test( ) ; extern mexLocalFunctionTable local function table test;

extern mwArray test(mwArray * b, mwArray x = mwArray: : DIN, mwArray y = mwArray: : DIN) ; # ifdef cplusplus extern“C” # endif

void mlxTest( int nlhs, mxArray * plhs[ ] , int nrhs, mxArray * prhs[ ] ) ; # endif

在VC 中调用test 函数的主程序文件如下: # include < iostream. h> # include “test. hpp” void main( ) {

double data[ ] = {1, 3, 2, 4};

mwArray a( 2, 2, data) , b( 2, 2, data) , c, d; c= test(&d, a, b) ;

cout< < a< < end1< < b< < end1; cout< < c< < end1< < d< < end1;

cout< < inv( a) < < det( b) < < end1; }

15

学 士 学 位 论 文

BACHELOR ’S THESIS 从上面可看出, 这时还可以直接调用MATLAB 的矩阵计算函数, 如求逆inv、求行列式det.

3.6 MATCOM

MATCOM 是由MathTools 公司开发的可以将M 文件转换成相同功能的C 代码的工具软件, 功能比MCC 命令更强大,它在一定程度上解决了代码复用、执行效率和源代码保密等问题。开发人员可以将一些在C 中实现起来比较复杂,而用MATLAB 的库函数更容易解决的底层工作如数值分析等交给MATLAB 来实现, 并通过MATLAB 转换为C 代码, 再加入到C工程中的适当位置。最后生成可以脱离MATLAB 环境独立运行的程序, 开发出具有自主版权的软件。[13][15]

MATLAB包括数学函数和工具箱函数,MATCOM已经将一般数学函数进行编译,可以遵循MATCOM语言规则直接在C中使用;要使用工具箱函数,则需要在MATCOM下编译MATLAB的M文件。

MATLAB 和MCC 命令类似, 在代码转换过程中产生大量的冗余代码,代码可读性差。而且实际执行效率提高得并不多。实践证明, 对MATLAB 中大规模数据处理程序中瓶颈部分用MATLAB或MCC 命令转换成C 代码后速度可以加快约一倍, 而如果用自己编写的C 语言MEX 程序实现, 速度可以提高上百倍。

[11][1]

在C 的程序里直接书写类MATCOM 语句

按照MATCOM 的语法, 在C 中直接书写类MATCOM语句. 例如: void testcom( void) {

InitM(MATCOM VERSION) ; / / 初始化Matcom 进程 Mm x, s, c; / / 定义变量, Mm 为Matcom 的矩阵类 X= colon( 0, 0, 0, 01. 10) ; / / 类似for 循环语句 S= sin( x) ; / / 正弦函数 C= cos( x) ; / / 余弦函数

Plot( (CL( x) , c, x, s, ) ) ; / / 画出正弦和余弦函数 ExitM( ) ; / / 退出Matcom 进程 }

16

学 士 学 位 论 文

BACHELOR ’S THESIS testcom 这个函数是在C 的源程序里直接书写MATCOM 语句, 其中所有的变量x, s, c 都是一个序列数, 而不是一个单独的值. 在过程开始时必须初始化MATCOM进程, 即InitM(MATCOM VERSION) ; 当书写完MATCOM 语句结束过程时, 需要退出MATCOM 进程, 如程序中的exitM( ) . 其中的colon( ) 函数和plot( ) 函数都是MATCOM 下的函数. colon( 0. 0, 0. 01, 10) 类似一个for ( x= 0. 0; x< 10; x= x+ 0. 01) 的循环语句. MATCOM 优于MATLAB 的主要地方是MATCOM 支持图形, 即支持Plot( ) 函数和其他图形函数在C 中直接应用.[17]

4. C语言MEX文件的实现

C语言MEX文件的实现包括,源程序的编译、MEX的编译和调试。在编译和调试前要进行编译器的配置。

4.1 C语言MEX文件的编写

C语言MEX文件的编写格式,除了要遵循C语言语法外,还须要加入用于MATLAB和C 语言通信协议---入口子程序。我们首先看一个极简单的C语言MEX文件,该程序的作用是两个数求和,源程序如下:

/ / 示例程序 myplus. c: 求两个 Double 数之和

# include 0 mex. h0 / * 计算功能子程序* /

void myplus( double y[ ] , double x[ ] , double z[ ] ) {

y[ 0] = x[ 0] + z[ 0] ; }

/ * 以下是入口子程序* /

void mexF unction( int nlhs, mxArray * plhs[ ] , intnrhs, const mxArray * prhs[ ] )

{

17

学 士 学 位 论 文

BACHELOR ’S THESIS double * x, * y, * z; int mrows0, ncols0; int mrows1, ncols1;

/ * 检查输入输出变量个数* / if( nrhs! = 2)

mexErrMsgT xt (0 Two inputs arquired0 ) ; else

if( nlhs> 1) mexErrMsgT xt ( 0 T oo many outputargument s0 ) ; / * 输入量必须是两个非复数 double 类型* / mrows0= mxGet M( prhs[ 0] ) ; ncols0= mxGetN( prhs[ 0] ) ;

if( ! mxIsDouble( prhs[ 0] ) | | mxIsComplex( prhs[ 0] ) | | ! ( mrows0= = 1& & ncols0= = 1) )

mexErrMsgT xt ( 0 Input s must be all noncomplex scalar double. 0 ) ; mrows1= mxGet M( prhs[ 1] ) ; ncols1= mxGetN( prhs[ 1] ) ;

if( ! mxIsDouble( prhs[ 1] ) | | mxIsComplex( prhs[ 1] ) | | ! ( mrows1= = 1& & ncols1= = 1) )

mexErrMsgT xt ( 0 Input s must be all noncomplex scalar double. 0 ) ; if( mrows0! = mrows1| | ncols0! = ncols1)

mexErrMsgT xt ( 0 Input s must be same dimen2 sion. 0 ) ; / * 为返回参数创建矩阵* /

plhs [ 0 ] = mxCreat eDoubleMatrix ( mrows0,ncols0, mxREAL) ; x= mxGet Pr( prhs[ 0] ) ; z= mxGetPr( prhs[ 1] ) ;

y= mxGetPr( plhs[ 0] ) ;

/ * 调用计算功能子程序 myplus( ) * / myplus( y, x, z) ; }

上面程序为一典型的 C 语言 MEX 文件, 程序由两部分构成: 一个计功能

18

学 士 学 位 论 文

BACHELOR ’S THESIS 子程序( myplus( ) 函数) 和两部分构成: 一个计算功能子程序( myplus( ) 函数) 和算功能子程序包含所有实际所需完成的功能、算法, 我们已有的或现编的 C/ C+ + 、FORTRAN 程序就被当做计算功能子程序使用, 它由入口子程序调用. 入口子程序是 MAT LAB 系统和外 部程序之间沟 通的桥梁, 主要用来完成两者之间的通信. 上面示例程序中, mexFunct ion( ) 函数有大量语句是用于检 查变量的数据类型等辅助性工作, 这是必要的, 因为 MATLAB 语言不像 C/ C+ + 等语言变量 使用前须声明, 对类型的检查可以避免许多错误的发生。[18]

下面简要的说明一下上面程序中用到的 MAT LAB AP I 函数, 它们在 mex. h 或 mat rix. h 中声明. mexF unction( ) , 入口子程序函数, 其格式如下:

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

{

, , / / 一些必要的代码, 用来完成 MATLAB 系统与计算功能子程序之间的通信

}

其参数的含意为: nrhs 和 nlhs, 整型变量, 分别为调用 MEX 文件时输入、输出参数的个数. prhs、plhs, 指针数组, 其元素分别为指向输入、输出参数的指针. mexErrMsgT xt ( ) , 用于输出错误信息, 并返回到MATLAB 命令提示符下.

mxGetM( ) 和 mxGetN ( ) , 获得矩阵的行 数和列mxGetM( ) 和 mxGetN ( ) , 获得矩阵的行 数和列mxGetM( prhs 0] ) 的作用为: 得到第一个输入实参的行数, 并赋值给整型变量 mrows0.

mxIsDouble( ) 、mxIsComplex( ) , 判断矩阵是否为双精度型、复数型. 输入参数 为阵指针, 返回 值为BOOL 值.

mxCreat eDoubleMatrix( int m, int n, mxComplex2it y complexFlag) , 创建一个未赋值双精度矩阵, m,n 为创建矩阵的行、列数, complexFlag 为标识是实数还是复数. 该函数返回所创建 矩阵的指针。

mxGetP r( ) 获得矩阵实数部分的指针, 输入参数为矩阵的指针, 回值为矩阵实部分的双精度指针。

MATLAB API 函数还包含其它许多接口函数, 分为 mx2函数和 mex2函数, 详细情况可查阅相关文献。

19

学 士 学 位 论 文

BACHELOR ’S THESIS MEX 源程序编写完成后, 还要经过编译后才能生成 dll 文件, 供MATLAB 或其它程序调用, 编译前要对 MATLAB 进行编译器的配置.

4.2 编译器的配置

编译器的配置是通过MATLAB的配置文件( mexopts. bat ) 进行的, 其具体过程为: 在 MATLAB命令窗口下键入: mex2steup , 随后系统弹出一个DOS窗口, 按照提示一步步选择完成即可. 该命令可带许多参数, 可针对不同的操作系统进行多种配置。[4][16]

4.3 C

语言MEX文件的编译

编译方法很简单, 直接在 MATLAB 命令提示符下键入: mex filename, 其中 filename 为需编译的源程序名. 如果提示有错误信息, 需查错, 修改源程序、调试. 直到没有错误信息提示. 编译通过生成的可执行的 dll 文件, 可在 MATLAB 命令提示符下或 其它程序中调用.

4.4 举例说明C的 MEX源程序的编写和调用过程

首先看一个最简单的例子:

# include “mex. h”/ * 必须包含的头文件* / void Mul( double * x, double * y, double * z) {

* z = ( * x) * ( * y) ; }/ * 函数的功能是实现两个数的相乘* / void mexFunction( int nlhs, mxArray * plhs[ ] , int nrhs, const mxArray * prhs[ ] ) {

double * x, * y, * z;

20

学 士 学 位 论 文

BACHELOR ’S THESIS = 1

1

int row0, col0; int row1, col1;

/ * 检查输入输出变量的个数* / if( nrhs ! = 2)

mexErrMsgT xt( “two input required. ”) ; else

if( nlhs > 1)

mexErrMsgTxt ( “too many output arguments. ”) ; / * 输入的元素必须为两个非复数的double类型数据* / row0= mxGetM( prhs[ 0] ) ; col0= mxGetN( prhs[ 0] ) ;

if ( ! mxIsDouble ( prhs [ 0] ) ? ?mxIsComplex( prhs[ 0] ) ?? ! ( row0 = && col0 = = 1) )mexErrMsgTxt ( “inputs must benocomplex scalar double. ”) ;

row1 = mxGetM( prhs[ 1] ) ;

col1 = mxGetN( prhs[ 1] ) ;

if( ! mxIsDouble( prhs[ 1] ) ?? mxIsComplex( prhs[ 1] ) ??! ( row1 = = && col1 = = 1) )mexErrMsgTxt ( “inputs must benocomplex scalar double. ”) ;

/ * 为返回参数创建矩阵* /

plhs [ 0] = mxCreateDoubleMatrix ( row0,col0, mxREAL) ; / * 为输入输出参数赋值* / x= mxGetPr ( prhs[ 0] ) ; y= mxGetPr( prhs[ 1] ) ; z= mxGetPr( plhs[ 0] ) ; / * 调用C 函数Mul* / Mul( x, y, z) ; }

21

学 士 学 位 论 文

BACHELOR ’S THESIS 这个例子实现的是两个数的相乘, 各个语句的含义请参见注释; 以mx, mex 开头的函数是Matlab与C 的接口函数, 具体用法请参见Matlab 的帮助。该例子的源程序主要由两个不同的部分组成:

1) 计算子程序。它包含了所有实际完成计算功能的源代码, 用来完成实际的计算工作;

2) 入口子程序。它是计算子例行程序Matlab

环境之间的接口, 用来完成两者之间的通信任务。入口子例行程序的名称为mexFunction, 拥有四个参数, 分别为prhs、nrhs、plhs 和nlhs, 其中prhs 为一个

mxArray 结构体类型的指针数组, 该数组的数组元素按顺序指向所有的输入参数; nrhs 为整数类型,它标明了输入参数的个数; plhs 同样为一个mxArray 结构体类型的指针数组, 该数组的数组元素按顺序指向所有的输出参数; nlhs 为整数类型, 它标明了输出参数的个数。[20]

以上两个步骤是典型的C 语言Mex 文件格式。为了能够在Matlab 环境下运行这个程序, 必须首先配置Mex 的编译环境, 其配置工作可在Matlab 环境中运行mex-setup 命令并按提示进行操作。配置之后, 在Matlab 环境下运行mex filename. c 编译C 文件, 然后可在当前目录下看到一个与C 文件同名的dll 文件, 到此为止已经大功告成。在Matlab 环境下键入filename( 2, 3) 看看结果, 检验一下是否正确。

以上是个非常简单的例子。在C 语言编程中经常用到结构, 下面是一个与

数据结构有关的例子。

# include “mex. h” struct Point {

double x; double y; double z; };

void Add( struct Point * p) {

p- > x + + ;

22

学 士 学 位 论 文

BACHELOR ’S THESIS p- > y + + ; p- > z + + ; }

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

const char * fnames[ 3] ; int nfields, n, i; mxArray * tmp; struct Point p1; double * x[ 3] ; if( nrhs ! = 1)

mexErrMsgT xt( “one input required. ”) ; else if( nlhs > 1)

mexErrMsgTxt ( “too many output argument. ”) ; else if( ! mxIsStruct( prhs[ 0] ) )

mexErrMsgTxt ( “input must be astructure. ”) ; / * 求得输入结构体的域数和每个域的元素个数* / nfields= mxGetNumberOfFields( prhs[ 0] ) ; n= mxGetNumberOfElements( prhs[ 0] ) ; for( i= 0; i < nfields; i + + ) / * 获得各域的域名* / fnames [ i] = mxGetFieldNameByNumber( prhs[ 0] , i) ; for( i= 0; i < nfields; i + + ) / * 从输入的结构体中取得数据* / {

tmp = mxGetField ( prhs [ 0] , 0, fnames[ i] ) ; if(mxIsDouble( tmp) ! = 1)

mexErrMsgTxt( “Element is not type of double. ”) ; x[ i] = mxGetPr( tmp) ; }

p1. x = * ( x[ 0] ) ;

23

学 士 学 位 论 文

BACHELOR ’S THESIS p1. y = * ( x[ 1] ) ; p1. z = * ( x[ 2] ) ; Add(&p1) ;

/ * 对输出的结构体矩阵进行初始化并赋值* / plhs [ 0 ] = mxCreateStructMatrix ( 1, 1,nfields, fnames) ; tmp= mxCreateScalarDouble( p1. x) ; mxSetField( plhs[ 0] , 0, fnames[ 0] , tmp) ; tmp= mxCreateScalarDouble( p1. y) ; mxSetField( plhs[ 0] , 0, fnames[ 1] , tmp) ; tmp= mxCreateScalarDouble( p1. z) ; mxSetField( plhs[ 0] , 0, fnames[ 2] , tmp) ; }

这个例子同第一个的格式是一样的, 区别在于一些mx 函数的使用上。对于Matlab 中的结构类型, 其实质还是数组。因此, 不一定非要使用上面的实现方式, 上面的实现方式是考虑到Matlab 的结构类型和C 语言中的结构形式相对应。

上面举的两个例子都是单个文件的, 如果C 函数用到多个文件中的函数, 编译时的格式如下: mexfile1. c file2. c …, 编译后将产生file1. dll 的动态链接库文件, 可在Matlab 工作环境中直接执行。注意:mex 命令可以操作多种文件格式, 包括. c、. obj 和.lib; 在链接多个文件时, 生成的Mex 文件的名字为文件列表中的第一个文件的名字; 在将文件列表时,必须写出文件扩展名, 并且用空格分开。

5. 结语

本文对MATLAB与C语言混合编程的常用方法进行了论述。各种方法各有其优势,又个又不足(如:利用C语言编写的MEX程序,克服了脚本语言速度缓慢的缺点,提高了程序执行的效率,是提高MATLAB程序运行速度的最有效方法,但不能脱离MATLAB;利用MATLAB引擎,可以在C中向MATLAB发送命令,控制MATLAB的运行,这是调用MATLAB最简单、最直接的途径,但要求必须由MATLAB在后台执行引擎发出的命令,不能脱离MATLAB独立运行;利用MATLAB编译器,可以创建脱离MATLAB而独立运行的可执行程

24

学 士 学 位 论 文

BACHELOR ’S THESIS 序,MATLAB编译器支持MATLAB绝大部分功能,但也有些文件是MATLAB编译器不能编译的,同时,独立可执行程序不能调用simulink函数;利用MATCOM技术可将MATLAB源代码译成同等功能的C源代码,既保持了MATLAB的优良算法,又保持了C的高执行效率;等等)。[17][18]

需要MATLAB后台支持的方法可以更好的与MATLAB结合,满足用户更多的需要,但限制了应用程序的普及与推广。独立于MATLAB环境之外的方法可以在满足基本需要的情况下被更好的应用和推广,但功能和方法受限,在实际应用中应根据不同的需要和所处的软硬件环境选择适合的方法,以期达到最佳效果。如果开发系统中考虑到数据传递的实时性,则采用独立于MATLAB环境之外的方法,会取得良好的效果;如果开发系统算法复杂,不要求实时性,则采用需要MATLAB后台支持的方法更好些。[19][21]

将MATLAB丰富的功能与C语言的强大功能相结合的方法,对于熟练掌握高级语言的工程技术人员来说,特别是对从事控制的工程技术人员都有非常重要的现实意义。

25

学 士 学 位 论 文

BACHELOR ’S THESIS 参考文献

[1]朱传安 ,潘大夫.Matlab 与C/C++混合编程接口及应用[J].安徽东风机电科技股份有限公司

[2]谭浩强.C程序设计 (第三版)[M] .清华大学出版社,2005 [3]张亮,王继阳.MATLAB与C/C++混合编程[M].人民邮电出版社

[4]飞思科技产品研发中心.MATLAB6.5应用程序接口编程[M]北京.电子工业出版社,2000

[5]刘卫国.MATLAB程序设计与应用(第二版)[M].高等教育出版社

[6]陈建平.罗先启 MATLAB 与C/ C+ + 、FORTRAN 语言混合编程[J].三峡大学学报( 自然科学版)

[7]潘大夫,汪渤等.Matlab 与C/C++混合编程[J].技术研究.北京理工大学信息科学技术学院自动控制系.北京,100081

[8]谭志芳,刘一峰等. Matlab 与C/C++语言混合编程的几种方法[J].内蒙古工业大学计算中心

[9]陶红,袁金荣. MATLAB与C/Visual C++混合编程的实现[J].上海理工大学城建学院,同济大学地下建筑与工程系

[10]杨李成,杨智. MATLAB 与CPVisual C+ + 混合编程的实现[J].甘肃工业大学电气与信息工程系,甘肃兰州

[11]邹益民.MTLAB与C语言的混合编程[J].智慧密集

[12]张灵研,石立华等.MA T L A B 与C 语言混合编程测试系统[J].解放军理工大学

[13]郭虹,薄云飞等.VC++与MATLAB混合编程技术研究[J].信息工程大学信息技术学院,郑州

[13]李天昀,葛临东.综述MATLAB 与VC+ + 的交互编程[J].郑州信息工程大学信息工程学院,河南郑州

[14]彭红梅,吴黎兵等.在C\\C+ + 中调用Matlab[J].武汉大学医学院计算中心,武汉

[15]李卫刚.基于MEX 文件的MATLAB 与C 语言接口的实现[J].武警工程学院基础部,陕西西安

[16]董桂生.Visual C+ + 调用Matlab 的探讨[J].洛阳工业高等专科学校计算机系,

26

学 士 学 位 论 文

BACHELOR ’S THESIS 河南洛阳

[17]于国丰,马孝义.VC++调用MATLAB的方法[J].电脑学习第3期

[18]蔡云飞,王朝玉.MATLAB C 数学函数库在C 语言中的应用[J].天津轻工业学院自动化系,天津

[19]周正人,张凤霞等.Matlab 与C/ C+ + 的接口及其在仿真中的应用[J].中国航空工业洛阳电光设备研究所,河南洛阳

[20]程建,廖正和.Matlab 与C 语言程序的应用编程接口[J].安徽理工大学计算机学院安徽淮南

[21]霍玲玲,王宏漫等.基于MATLAB 编译器和MEX 文件的VC++与MATLAB 混合编程[J].辽宁师范大学计算机与信息技术学院.大连

27

学 士 学 位 论 文

BACHELOR ’S THESIS 致 谢

经过四年学习,籍论文完成之际,我特向指导和帮助我的老师、同学、朋友及关心支持我的家人表示诚挚的谢意。

首先要感谢我的导师何老师。本文是在导师何老师的精心指导下完成的,从论文的选题、设计方案直至完成论文的整个过程中,都得到了何老师耐心细致的指导。何老师严谨的治学态度、渊博的学识、独特的学术思维、一丝不苟的工作作风、热情待人的品质,使我满怀敬意。

感谢师范学院所有的领导和老师,四年的学习基础对我非常重要,感谢喀什师范学院物理系所有老师和领导,在撰写论文中得到了你们支持和帮助。 感谢我亲爱的同学们,在学习中我们相互帮助,互相激励和关心。 感谢我的家人,这么多年来,正是你们的支持和鼓励,才使我顺利地完成学业;正是你们的关心和默默的奉献,给我创造了优越的条件,使我在学习的道路上乐观向上、勇往直前。

28

本文来源:https://www.bwwdw.com/article/qxa7.html

Top