- 在线时间
- 51 小时
- 最后登录
- 2014-2-12
- 注册时间
- 2012-3-10
- 听众数
- 5
- 收听数
- 0
- 能力
- 0 分
- 体力
- 592 点
- 威望
- 0 点
- 阅读权限
- 30
- 积分
- 230
- 相册
- 0
- 日志
- 0
- 记录
- 3
- 帖子
- 101
- 主题
- 18
- 精华
- 0
- 分享
- 0
- 好友
- 18
升级   65% TA的每日心情 | 开心 2014-2-12 10:47 |
|---|
签到天数: 52 天 [LV.5]常住居民I
 群组: Matlab讨论组 群组: C 语言讨论组 群组: 学术交流B 群组: 学术交流A 群组: 2013年数学建模国赛备 |
8 O6 t, {- V& {0 y+ k# L. u- u8 a9 SMatlab调用c程序
; j7 E% Q j% h; b6 g文章来源:不详 作者:佚名
/ |+ a( C+ \, D" Y$ a: c& U
" ?' y6 o% k/ _7 c--------------------------------------------------------------------------------6 y0 O* r) h- f0 d% K
0 D. L$ R a g该文章讲述了Matlab调用c程序.* I4 X S' D. s4 v0 O$ A6 x4 P f- Y1 z
6 |" K6 O0 g0 u3 F方法:! J- }( O& v& F
第一步:要先在matlab中安装c程序编译器,步骤如下:, Q0 f9 W: F1 @
键入命令:mex -setup;
+ g' Q$ f& @/ Y& c' K8 Z选择c/c++编译器; d5 p; U* P5 ^* ~3 G
选择c/c++编译器版本;6 w% s9 R7 h' K& u# S1 ^) v
确认。) ]# @6 C& L: M1 D3 g* A
第二步:键入:mex *.c$ [* I7 Z$ V7 E* C1 D4 G7 R) l
9 i2 C1 z. w f2 T! r
*********************************************************************************************************************************************
: a) b6 K: c& O: |- Z. R. u$ W# k& m7 \7 u$ E% F. F
实例介绍:【转】
) v. L( L" L1 B h6 b0 y+ n. ?2 i; e+ h: p# U$ \
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
9 L, d9 c& o% w, m- zdouble add(double x, double y) {1 [5 E8 l2 ?; w- r+ `4 m8 d
return x + y;* W0 ]0 U u8 h5 f5 d3 c9 k: `+ N
}
# \. j% T" ^3 Q& ^8 f |6 a现在我想要在Matlab中使用它,比如输入:0 }5 Y" X) q4 q$ h7 n7 Z% A
>> a = add(1.1, 2.2) K+ c1 Q) J% ^' u$ z ~0 f
3.3000. u* x8 k5 s* J
要得出以上的结果,那应该怎样做呢?
, y! k- Z- K `- Y7 y解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
$ A3 Z$ E# P/ |7 y" ^- p可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
' k/ }8 c2 `- ^8 V; E所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
1 s& c3 b" M4 l1 q2 z7 X5 G w2 C比如该C文件已写好,名为add.c。那么在Matlab中,输入:
+ p& j9 W$ ]" z9 S$ M P>> mex add.c. E" K4 r- Y. r( h0 O
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
* `6 D' Y; v, U9 a' {9 E* G$ H我们现在来说mexFunction怎样写。' c J# F2 ^" z! K% y! O* Y; \/ A
mexFunction的定义为:( l0 H- Q: \. y( v- q' U9 q
void mexFunction(
+ y5 u7 T8 ]! L. E int nlhs,
. X. s: c7 d Q/ f" x& k mxArray *plhs[],
4 P$ M- E0 y W int nrhs,
1 r9 c. |# H% n, ?: g- t! { const mxArray *prhs[]) {4 s; `: H. J- c$ N' _; r j
2 T/ f, b, s& Q) |, v& c
}6 N2 V; Y. {- z) D
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:' [' F1 |, m: n/ E
>> b = 1.1; c = 2.2;
, C! w# t9 I; v>> a = add(b, c)
8 ]2 b% t+ M6 T7 YmexFunction四个参数的意思为:
$ S' H! M; A, Q/ C& Qnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。) r+ O9 K# X* @2 x6 \
nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
/ Z( A. M2 u, B3 F7 M& [plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
& B- Y+ Z0 ?7 t4 X; \prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。; {$ R2 i& y9 ]( u% l/ ]9 E$ |
因为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类型的指针数组。
' {" R, e7 F |0 k5 c完整的add.c如下:
, X* z# I! y' S8 E, f+ W# j/ ?4 I4 U// add.c9 D8 M. [! N S
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
% Y( q' f6 x! g2 G. |double add(double x, double y) {
5 M. P. C. m( j& B1 w! v8 G return x + y;
: S. M& {. G1 l5 B} // MEX文件接口函数
& l, `. q3 \ W0 C, O/ Q o0 mvoid mexFunction(8 i2 q7 ~* Q; v- c* i
int nlhs,
: g7 U0 i4 y/ x7 C2 u mxArray *plhs[],2 y4 y' L! y& w8 ?+ @' Y! X* T/ f. j
int nrhs,
2 @& x+ r. G6 a _( e( | const mxArray *prhs[]) {8 K# ^5 o! X: n" o
double *a;* `0 n6 v3 x7 j6 c0 w7 N/ O- O, J
double b, c;; t! p% P( v/ @+ @5 ]! |
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
$ o. _! s; E/ L# M" a" B4 S. n, q a = mxGetPr(plhs[0]);7 S3 ]. |/ C6 m7 a
b = *(mxGetPr(prhs[0]));
. w# R1 j; j* y# ~& I0 ` ] c = *(mxGetPr(prhs[1]));
0 g1 b# r6 P# \' R2 \, U9 u7 n6 P( d *a = add(b, c);
% g/ K, H$ E7 n$ V2 F}
0 [: d# A' Y. k* }( t6 r; @mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
& V* S! X5 G" m% }) A7 w$ v>> output = add(1.1, 2.2);
7 B/ o6 E+ T5 F6 w" n3 y2 X在未涉及具体的计算时,output的值是未知的,是未赋值的。所以在具体的程序中,我们建立一个1x1的实double矩阵(使用mxCreateDoubleMatrix函数,其返回指向刚建立的mxArray的指针),然后令plhs[0]指向它。接着令指针a指向plhs[0]所指向的mxArray的第一个元素(使用mxGetPr函数,返回指向mxArray的首元素的指针)。同样地,我们把prhs[0]和prhs[1]所指向的元素(即1.1和2.2)取出来赋给b和c。于是我们可以把b和c作自变量传给函数add,得出给果赋给指针a所指向的mxArray中的元素。因为a是指向plhs[0]所指向的mxArray的元素,所以最后作输出时,plhs[0]所指向的mxArray赋值给output,则output便是已计算好的结果了。
5 U; u6 u# d; t0 i. w9 {! W上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
# M0 g! {% D/ H9 t1 c实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
6 B U3 ?" V, i& M. ~输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
$ `- O% K* p0 q7 _# T( g8 M: Z0 o从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。5 I/ Y' L, n2 }. O
5 b6 m0 b- F) c, ^# w1 h+ G
*********************************************************************************************************************************************& W$ x3 Y9 q, |+ n5 s4 T3 N
' \# e- u( c$ Y8 A. wmex 的目的,
2 k; B7 _9 k& Z8 s7 p2 A2 B8 U) y3 b5 o" R+ j! C$ E
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:3 L6 ]; K- j [% f- F
8 g! i& l- k( F9 m* _
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
+ D; s, m8 Y0 N- X6 M
6 P, D6 {2 D# P+ q, i2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
5 \- K% |( w; b$ W. Y2 t' K, P+ S% Z; G$ ~/ L, u- E! y+ K( }
3、据称可以弥补Matlab硬件设备接口的薄弱环节., M; ? c" Q0 {1 L! O6 U9 F0 u% p: x9 |
; P) I) U; ~5 b: I/ \- Z# y
今天写了第一个使用MEX.: V, w* {' s9 u9 V5 g" g3 F
0 K% d9 e5 j, e+ J# O8 ^, f
一个简单的对Matlab普通数值矩阵的操作.+ B, `$ Q3 H) R6 _# J
5 |/ C4 u$ g' Q. A
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以1 l3 l5 F! @2 O. C
4 s+ j' F/ R4 }( M" c: r( q
一律用int代替.# l! ~9 w$ L0 Y& j- w! H6 G
" u* H* l& ?/ |* I
#include "mex.h"
& C' m8 z8 P/ t4 s#include <iostream>
# a# F% R" P& {, h
H1 t3 R) i9 `2 [6 B' cvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
7 \4 p/ b9 y8 j0 m7 K{
/ t. b4 [5 a* L0 Y: v
4 L0 b% y c; c# S. V9 R- a/ I2 ~9 Lint i,j,k;
( T4 k; o: S$ Z& u( f. B' X; A: x3 yint index;' P% \6 b4 o& d+ n7 F% h6 O. s* N5 j
double* pr=NULL;
5 w+ {2 {0 c- t2 z/ X* x/ ^double* pi=NULL;9 w" K$ ?2 h9 J9 Z7 O9 E* U
int M,N;
3 n' t2 A8 C8 Gint ndim;
/ H* `! R1 m9 Bint dims[2];
& p6 q1 A2 C0 }, V$ v- |4 kfor (i=0;i<nrhs;i++)
: Z a! @* w: f! w{- N+ P2 [/ [! a
if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
# p7 N% ?; K# Z# D( S {
& @4 [8 J$ \$ n W& B6 _2 G pr=mxGetPr(prhs);+ x- V6 V' M% X2 M
pi=mxGetPi(prhs);
8 ^! J+ i9 r9 h% { M=mxGetM(prhs);, E7 z Z, a. I3 ~
N=mxGetN(prhs);% e0 q/ y8 P& g1 H0 l: _9 B3 L& c* T& u
ndim=mxGetNumberOfDimensions(prhs);- f; ]9 @$ I8 }
4 i d8 C5 e0 W9 Q; w4 a3 d0 i mexPrintf("变量%d:\n",i);
, C" T6 f9 W4 T% ]# L for (j=0;j<M;j++)
x; u$ g8 _% K' ]+ G6 ~( ^% g {
) |' ~$ ]' A" h; }5 _# m dims[0]=j;
3 R$ T: [& Z* s1 p for (k=0;k<N;k++)7 z6 d, ^2 N6 C/ |
{7 A( s4 u$ g! @5 I
dims[1]=k;* z5 E0 ` _# ?7 T) c
index=mxCalcSingleSubscript(prhs,ndim,dims);0 L1 M0 p# K" I; Z, L9 p2 U
if (pi==NULL)
: A" j/ A6 b8 L0 ^& O {
! I* @7 x0 I9 M1 a mexPrintf("%6.2f",pr[index]);% o/ s3 x3 W; ]5 B0 R$ e/ V
}
3 P3 R0 y4 y3 {! l+ @. k else{
9 y2 t7 Y! X& b4 p8 ]3 \ mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
, z1 B; i; x; m' P" O% q6 ^3 w }; w: l0 t; q+ o" U5 N+ F8 A5 N
}
$ ]- p. D u2 t0 T7 I, ^0 ~% a mexPrintf("\n");
/ z& l" l- o8 H; C# a- G( v0 A+ O2 e, c
}1 j5 i; S$ A( p
3 V: V K% p6 h }9 Q1 s( E7 S0 X" V" V
else{
* `+ V* N7 V; j" V mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);2 ^/ t. S- X' Q1 j2 E6 z( u
}
) F0 U& @( q& k5 P9 W# d* q$ R! x4 |) q
C K" p% r: U2 S7 i
}9 x, n' W$ r* I- R/ v! }
( K/ v/ r& n# S8 e4 d$ E+ @}2 [% {1 ?9 v d/ D$ ?" D7 W& d! x
: F2 p% |# J4 M7 g; J0 ]& ]1 eResult:
1 N, p8 X- [! `$ x- a# Z+ r, }4 u& ~ f0 w( w; \4 x- i
>>mex test.cpp
2 O0 M7 h5 L3 U6 F>> test(a,b,c)
* @* ?) N5 _6 c7 I: i变量0:) D6 s, `5 i' N# E. F) u4 D
0.35 0.62 0.83
; M7 F6 M, S$ |; o- f0.20 0.47 0.59
8 h! v$ b H) d9 i. A0 p0.25 0.35 0.55
# a4 p; ^( ] p( @" x# W- Q变量1:
$ n" @. k$ T. r; X3 _3 t0.92 0.38 0.53 0.57
% z- Z5 T- {2 O( d4 c0.29 0.57 0.78 0.47/ t' l" c, r P7 D$ [3 ~
0.76 0.08 0.93 0.01( t1 `6 M: W7 z* R) V0 ?
0.75 0.05 0.13 0.34
" Y3 \; ~8 X) y5 r9 i: r变量2:
1 h8 ^( u8 D2 Q" P0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j, S/ E6 k$ \! E5 `8 C- \4 r
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
4 Q- s3 Y8 }: A3 g+ q8 m1 P0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
6 O: J* o5 k; @# R1 @0 g0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
5 l2 ~0 U. X- J$ V! ]0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
5 M, t! | D! s) z( M# j0 Q# k6 J>> help test- \- V# a3 R, ^0 h9 u+ U
本程序用于调试mx______函数. Y' ]. g% }3 Z! r1 a1 r5 |4 H
% `' [, z+ q# y- N7 n1 ]6 z
& a1 m: U1 `# w% o% @& C! k7 k
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html7 B6 n# N$ h- v5 }4 a
. d( r/ t( R7 n7 M: w. X下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|