基于MEX文件的Matlab与C语言接口实例

转自:


如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:


double add(double x, double y)


{


return x + y;


}




现在我想要在Matlab中使用它,比如输入:


>> a = add(1.1, 2.2)


3.3000


可以通过MEX作为与C语言的接口来实现。MEX是一种动态连接子程序,可以用C语言编写。在Windows系统下后缀名为dll。


现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量传给 mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值。


完整的C程序如下:


#include "mex.h" // 使用MEX文件必须包含的头文件




// 执行具体工作的C函数


double add(double x, double y)


{


return x + y;


}




// MEX文件接口函数


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


{


double *a;


double b, c;


plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);


a = mxGetPr(plhs[0]);


b = *(mxGetPr(prhs[0]));


c = *(mxGetPr(prhs[1]));


*a = add(b, c);


}


我们现在来说mexFunction怎样写。 


mexFunction的定义为: 


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


{


/*....................................*/





可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时: 


>> b = 1.1; c = 2.2;


>> a = add(b, c) 


mexFunction四个参数的意思为: 


nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。


nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。



plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。


prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。 


因为Matlab最基本的单元为array,无论是什么类型也好,如有double array、 cell array、 struct array……所以a,b,c都是array,b = 1.1便是一个1x1的double array。而在C语言中,Matlab的array使用mxArray类型来表示。所以就不难明白为什么plhs和prhs都是指向mxArray类型的指针数组。


下面详细介绍如何用c语言编写mex文件:


2 编译器的安装与配置



要使用MATLAB编译器,用户计算机上应用事先安装与MATLAB适配的以下任何一种ANSI C/C++编译器:


5.0、6.0版的MicroSoft Visual C++(MSVC)


5.0、5.2、5.3、5.4、5.5版的Borland C++


LCC(由MATLAB自带,只能用来产生MEX文件) 


下面是安装与配置MATLAB编译器应用程序MEX的设置的步骤: 


(1)在MATLAB命令窗口中运行mex –setup,出现下列提示:


Please choose your compiler for building external interface (MEX) files:


Would you like mex to locate installed compilers [y]/n?




(2)选择y,MATLAB将自动搜索计算机上已安装的外部编译器的类型、版本及所在路径,并列出来让用户选择:


Select a compiler:


[1] Borland C++Builder version 6.0 in C:\Program Files\Borland


[2] Digital Visual Fortran version 6.0 in C:\Program Files\Microsoft Visual Studio


[3] Lcc C version 2.4 in D:\MATLAB6P5P1\sys\lcc


[4] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio


[0] None


Compiler:


(3)选择其中一种(在这里选择了3),MATLAB让用户进行确认:


Please verify your choices:


Compiler: Lcc C 2.4


Location: D:\MATLAB6P5P1\sys\lcc


Are these correct?([y]/n):




(4)选择y,结束MATLAB编译器的配置。 
matlab下演示:


>> mex -setup
Please choose your compiler for building external interface (MEX) files: 
 
Would you like mex to locate installed compilers [y]/n? y
 
Select a compiler: 
[1] Lcc C version 2.4 in D:\MATLAB7\sys\lcc 
[2] Microsoft Visual C/C++ version 6.0 in D:\Program Files\Microsoft Visual Studio 
 
[0] None 
 
Compiler: 2
 
Please verify your choices: 
 
Compiler: Microsoft Visual C/C++ 6.0 
Location: D:\Program Files\Microsoft Visual Studio 
 
Are these correct?([y]/n): y
 
Try to update options file: C:\Documents and Settings\Administrator\Application Data\MathWorks\MATLAB\R14\mexopts.bat 
From template:              D:\MATLAB7\BIN\WIN32\mexopts\msvc60opts.bat 
 
Done . . . 
 
>>


在Matlab command window下输入刚才编写好的C程序名。


如:


>> mex add.cpp


注意输入程序名的时候,需要在程序所在的当前路径下,否则会出现


D:\MATLAB7\BIN\WIN32\MEX.PL: Error: 'add.c' not found. 
 
??? Error using ==> mex
Unable to complete successfully


mex add.cpp顺利执行后会产生相应的add.dll文件,此时则可在Matlab下执行add程序。


输入及运行结果:


>> b=1;c=2;
>> a=add(b,c)


a =


     3





>> a=add(3,4)


a =


     7


对于c语言接口网上的资料是少之又少,所以下面这些文字全是我一个字一个字打印上来的希望大家 能对的起我的付出: 现在的程序员都面临大量的关于应用程序接口(Application Programming Interface,API) 的信息,大多数人都会使用API和程序库,并在其所写的每一个应用程序中实现它们,但是很少人 会创建或发布新的能广泛应用的API,事实上,程序员似乎倾向与循环使用他们自己的东西,而不 愿意查找,能满足他们要求的程序库,这或许是因为写特定应用程序代码要比查找设计好的API容易。 这里我所提到的是一种基于接口与其实现的设计方法,并且通过对24个接口及其实现的描述详细地演示了这种方法,这些接口涉及到计算机领域的很多知识,其中包括数据结构,算法,字符串处理 和并发程序,这些实现并不是简单的玩具----它们是为了在你们所设计的软件代码中使用而设计的。(当然了我会通过阅读量来看是否继续发下去,人要少了我就没有必要浪费时间了) c编程语言对基于接口设计方法的支持是极少的。 而面向对象的语言,如c++,Modula-3,则鼓励将接口与实现分离,基于接口的设计独立与任何特定 的语言,但是它要求程序员对像c一样的语言有更多的驾驭能力和更高的警惕性,因为这类语言很容易破坏带有隐含实现信息的接口,反之亦然。 然而一但掌握了基于接口的设计方法,就能够在服务于众多应用程序的通用接口基础上建立应用程序,从而加速开发,在一些c++环境中的基础类库就体现了这种效果。 增加对现有软件的重用---接口实现库,能够减少初始开发成本,同时还能减少维护成本,因为应用程序的更多部分都建立在经过良好测试的通用接口的实现上,这里我提到的接口是针对数据结构的,但它并不是数据结构,我重点将放在算法引擎----包装数据结构以供应用程序使用----而不在数据结构算法本身,接口的示例和实现都以literate程序的方式给出,换句话说就是源代码及其解释是按照最适合理解代码的顺序交织出现的。 下面我将我想要给大家讲的内容分一下类: 基础 1,接口与实现 2,异常与断言 3,内寸管理 4,进一步内寸管理 数据结构 5,链表 6,表格 7,集合 8,动态数组 9,序列 10,环 11,位向量 字符串 12,原子 13,格式化 14,低级字符串 15,高级字符串 算法 16,扩展精度算法 17,任意精度算法 18,多精度算法 线程 19,线程 建议: 看到这里的朋友我相信对c语言都有了很长时间的学习 如果你还没有搞懂c语言的全部内容,我强烈建议你先别看这里
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值