- 在线时间
- 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年数学建模国赛备 |
* B6 l* Y% k# I* h- y! ]; v' UMatlab调用c程序
* B3 ]- W; n- ?+ U" x文章来源:不详 作者:佚名
+ x5 e3 P, c) R* [6 e$ e% l5 G- q+ X$ A7 P# s/ a; w& S$ R- N
--------------------------------------------------------------------------------
1 y- @( n4 Q$ Q7 n+ y' p* p; ~! s+ D7 X6 _& W: j4 b4 y
该文章讲述了Matlab调用c程序.( `2 N$ r% E$ J0 z
j) }( ?$ G/ Z! u% G方法:
8 C9 R6 J; H8 L第一步:要先在matlab中安装c程序编译器,步骤如下:
# Q' R% V& C% J4 I8 @1 p' i0 t& \键入命令:mex -setup;
, H: F) c0 U ]6 d; ?$ g选择c/c++编译器;
) _7 w4 t, o4 _! A; K选择c/c++编译器版本;. N: J7 t' a) X$ h/ \7 _# i& r9 I
确认。- B* o, L% ~# x$ }8 ]
第二步:键入:mex *.c
9 K; K, [6 p! G* o( Z1 m) R) Q" J
*********************************************************************************************************************************************
8 K1 A1 F* X& G2 k* p( t. Z, i
- D! |& A( H/ ~6 G实例介绍:【转】
- C3 N% q4 r6 a
9 w6 g) ~; G6 ~1 A+ U如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
( I: A" T3 }5 H; n- N0 H( f n+ adouble add(double x, double y) {
9 v& L7 X# g% B return x + y;( _% y+ y( ?, R1 p( T S& J
}4 r# o1 U! w% u/ B8 j6 j
现在我想要在Matlab中使用它,比如输入:
/ T8 `$ |+ \2 d5 R8 S>> a = add(1.1, 2.2)/ ~( V/ y5 a5 w9 X3 l, @ b
3.3000
2 X! [$ C9 X/ n" m# K( G* G' m要得出以上的结果,那应该怎样做呢?
' u: h7 A( c# L解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
& w- j. H! {; \可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
U/ g9 m3 p3 }* V' l) I- K所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
6 m- ~6 C5 w- Q* `7 ]% V6 O2 z2 O; e比如该C文件已写好,名为add.c。那么在Matlab中,输入:: Q' g7 b% }0 ]8 O
>> mex add.c
. J1 N2 p1 h4 b1 z% [就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
5 |# A6 }: |% P# |我们现在来说mexFunction怎样写。
) w9 {% J* s* K- F3 W1 @ s# cmexFunction的定义为:) W9 J& l, A. j* ?
void mexFunction(: t' v/ y1 B- j1 M' l0 ?; `
int nlhs,
, E4 B% n1 \$ G+ k0 Y# T4 ~# ? mxArray *plhs[],
- E6 C% X$ @; Y; P1 D int nrhs,
5 T5 a$ V; r9 ]. a const mxArray *prhs[]) {
6 E' b6 [: V, f1 V$ p) O
' {5 ]1 J: f3 t) A}
- K* v' A, K4 I5 X可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
+ M3 h! ?5 R' o( ^3 R( E5 F7 j6 p>> b = 1.1; c = 2.2;$ X9 \: l+ n- I3 z& f R# e/ w1 o
>> a = add(b, c)
0 F; f+ q' w. W+ p5 YmexFunction四个参数的意思为:) [% w A8 h" I, ]6 R9 A
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
- C, n7 P! Z/ |nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
6 ~" s& W V8 z9 Fplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。2 F; z- N X( e3 h" j4 G
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。) n; ?$ x2 x- d, h0 v, m
因为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类型的指针数组。# W" ]7 ?1 U$ x
完整的add.c如下:
3 K" Z+ i7 i) A% o u// add.c% \/ e" _8 I; P! ^8 C' K( ^4 o
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
0 X: ~3 f9 K7 `- @) xdouble add(double x, double y) {0 X5 B4 F M7 v/ W/ \1 L
return x + y;7 @6 M# Y, S1 {& f: m
} // MEX文件接口函数
2 N0 l/ u$ @0 A3 Fvoid mexFunction(/ x% N2 c$ h$ `9 y x2 Y% {
int nlhs,: }( M7 n5 ?% K2 P" v! w: O1 U
mxArray *plhs[],
n" N, a$ z& Y* _ int nrhs,
) d2 Q8 B7 ^- z* e+ x const mxArray *prhs[]) {5 A/ b1 s$ c' ` e
double *a;
+ z* q) q: d2 r0 H1 k4 X; L" O double b, c;3 X* i- [) j1 K8 p1 _7 a3 ~
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);# e0 A: C; x6 L# g9 j+ e& R
a = mxGetPr(plhs[0]);# r- W3 G7 U0 v: r3 k% U8 J" @
b = *(mxGetPr(prhs[0]));2 i) h; b! d* U' |5 L) v! J" o* Q4 {/ T
c = *(mxGetPr(prhs[1]));2 K3 X! x; |" h! \; x
*a = add(b, c);
; q! }; T- q* L8 ?! K' ]3 i& w} , i" |6 v, h: K: X: Q
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:' d1 z2 _ }1 a3 K! S2 t' }* @
>> output = add(1.1, 2.2);' U& {% P1 K1 O/ X0 S2 d. D4 \1 D
在未涉及具体的计算时,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便是已计算好的结果了。7 \2 t$ y9 r: l( _
上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
2 b( \3 v+ N0 L1 R实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保! P2 ~" C4 I! e# f e, C3 r
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
+ W6 n/ q! x. a) i$ w/ R) \从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。9 `) K+ ?5 u5 e; W! P& n$ Z
5 n* @( y3 B2 \/ _$ C& E5 x*********************************************************************************************************************************************
/ ~4 D8 q; H; W; b& [0 H; ^/ O4 t- A+ r5 o3 i* ~
mex 的目的,
! E( F9 S4 C* h! V: W# |. B$ I+ ]& E' \# b2 g
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:; f5 l! m" R `. s3 J' h0 K) V
# |4 I2 A9 L% X ^
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
1 I0 T5 S" a" p b$ z5 I8 W7 r5 r0 X" i
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.( H. i. d& I' ^% S! E, M* v7 ^
7 z9 J0 ^8 q; [5 w3 q3、据称可以弥补Matlab硬件设备接口的薄弱环节.! W* c: n. k( w' f4 Q
% A) g) P" R: } f p
今天写了第一个使用MEX.3 `0 ]- z; i3 \0 ^4 D. C& d
8 F$ \ X1 X {( M3 L3 J一个简单的对Matlab普通数值矩阵的操作." `( c. K" P* M: R" X
W) ^, @: k+ O% @& n) o
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
- v& ^; T0 y; v0 c, t( b! y$ _+ _5 L1 ^" k$ ]) N3 `% D9 u0 B+ P0 |9 Z. ^
一律用int代替.3 c& B% Q, J, Y, w3 ]
/ j, F1 n# \5 _* p! ?( Q; i/ E9 J3 B
#include "mex.h"/ w& d8 L! D. D+ L
#include <iostream>+ l# m- A' N8 c g- W9 T
3 {3 f3 r% Y$ z- w' I) kvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
0 x- h' U) U2 V% R. c4 D c4 _{* g/ W; S9 \4 l
# e* }* e5 N$ M3 j4 I6 H' u# Nint i,j,k;' a) O4 D/ U) p$ O) O4 N# g! a* r
int index;
* @& M1 L, h2 m7 f2 ^double* pr=NULL;
& _( Y; H1 K+ z7 n& K7 y& ?double* pi=NULL;
: k4 H) ]5 Z/ v- Q/ j$ j8 g3 uint M,N;
" B5 i: R7 V6 C, p2 z; [) qint ndim;
) j- G3 ~' _/ Q; ?" _8 G) A5 _; M. \int dims[2];5 v7 N" K; ?7 q
for (i=0;i<nrhs;i++)
3 h# U1 i& j% A) L* x$ r{
# b8 u2 j5 r2 k5 ^( ^+ E if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
% x- s& k3 C: Y' n {
+ t: c8 f" O; v/ a( {1 K! R- }2 P pr=mxGetPr(prhs);4 a( s2 m+ m+ H* P n
pi=mxGetPi(prhs);
4 y* l$ O* T) ]7 t M=mxGetM(prhs);
5 S; g5 t5 {$ q$ j; \- a N=mxGetN(prhs);
0 h# k, K* q, ] ndim=mxGetNumberOfDimensions(prhs);3 k* f/ M* d- y" R e9 f
7 p- N+ A+ c2 B* e' B. U mexPrintf("变量%d:\n",i);
2 h( R- t R9 ]% I/ J for (j=0;j<M;j++)
! f, O+ ?6 ^) _. J! W, l" w- Y! u {
o, V' E1 o7 v: r* E dims[0]=j;
2 d/ B, Q$ Z" b% z5 J for (k=0;k<N;k++)
* s5 Q# y3 p- I# x9 i m {
& r5 `* [' }3 `) {- n6 w+ B0 ?, Y V dims[1]=k;* ^' \5 x, \; {6 ^6 Y1 s
index=mxCalcSingleSubscript(prhs,ndim,dims);
, u3 ]4 ?3 z$ J& T: q if (pi==NULL)
5 h5 f: G! G/ Z c! p {
% O1 u) L* z/ r. q) H2 K mexPrintf("%6.2f",pr[index]);& }$ O, d, }, }! _
}3 P4 U. A! i4 ^8 ~/ O/ z0 @
else{
. |- J& W6 P; o" }- t% S mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);4 W0 s6 s, }+ y) a( W
}% \# t ^$ t- A- S5 u
}. s" ~' ~- C3 O/ V+ X7 g& \1 ^- |9 M
mexPrintf("\n");7 R7 y' O2 K9 A8 M4 Z' Z
! j& G0 G) Q5 o% o
}
! s f8 U8 A. R% Q, m . ^6 A& v, [' _) O
}- j( B% Y! \8 _3 F( D& t2 B
else{/ q& G! d' j& Z# L/ @
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
( @. V1 b# B. R: k$ a0 r6 x# u. E} r) ~" Q$ D4 Z6 u, m" F
) t$ y$ e& i4 |5 q3 e
o2 L8 k- k4 N" r3 H}' D) U( v( K" b2 V; O3 X5 z3 f
9 A4 R3 n$ Q8 c+ m* ~3 b) F2 i
}2 \- M* g8 ?8 }' A. T w. i( M
$ H0 ~4 C I. _Result:- O I/ s4 Z* h# [/ Z- b" p- e! s
# C7 w6 l$ [7 s% }
>>mex test.cpp
" H/ X) l9 ^' O7 N>> test(a,b,c)
. R9 ^) s7 G0 C! d) D0 n6 a, ?变量0:
1 p9 B' c7 x: y B4 d0 Q$ I3 W0.35 0.62 0.836 ^$ ] `# C' \! M r; z9 @
0.20 0.47 0.59
- P' q6 G- C E$ W1 _0.25 0.35 0.55
+ N/ Z9 Q8 m/ w, b8 a/ O& n变量1:! K# Q- B2 z4 V& u3 ^/ l( I0 |
0.92 0.38 0.53 0.57
, `: C7 M8 c% y! o; ^9 b: n0.29 0.57 0.78 0.47
4 M+ D( Y3 z. O/ x3 Y! @- X0.76 0.08 0.93 0.01( ~0 W9 T2 ]' {( H! ~6 a
0.75 0.05 0.13 0.34
/ ^! G6 V! p& G# a" V变量2:% y9 w7 a0 [3 Q# p( S
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
3 o+ s0 t. q! Q% ?. V# H( A, T6 u0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j7 f; `( S! x0 X N
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
4 s( ?- w& r# j* N0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
4 m# e7 B! ?7 G* W, X$ x0 m0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j, _; V. _; n1 i1 K
>> help test
, U9 a" w3 g9 w/ {* Z( O" ?) l本程序用于调试mx______函数.# i' _: v4 t7 ~+ y. [. d
9 p# v: M3 t" I4 |4 a4 @7 |. ~' Q( M" z" p5 ~
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html# a }8 W/ i @
1 ~9 N+ u4 D, A
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|