- 在线时间
- 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年数学建模国赛备 |
& S5 I) b' c1 Z; K9 t7 OMatlab调用c程序8 ]" p& P* p% c. Y/ `
文章来源:不详 作者:佚名 2 Q! p2 j9 t6 f4 Q `; f+ y% W: `( p
$ F, J+ L: { X$ _2 Y--------------------------------------------------------------------------------
1 ^! F& j5 o. ?$ ?/ L1 o. ?* b/ b* S: v0 p- ?! M+ d0 | i0 b2 F
该文章讲述了Matlab调用c程序.3 ^% W4 K( `7 F0 f6 A; B+ M2 x
: G4 d# P4 P. u, u6 h! { y方法:
; t1 P9 F- o* A) w8 ~$ I0 i- J第一步:要先在matlab中安装c程序编译器,步骤如下:
4 Q" P% X: C! ~0 q( L$ u! i. e9 t键入命令:mex -setup;
& R. H* W/ A. q0 d+ |选择c/c++编译器;. l5 n% f( k' n, }+ z; v. _: k
选择c/c++编译器版本;% _, e. h" d6 L2 B1 G7 ~! f/ L
确认。
# R2 v6 t, ], H9 q; A0 S" L第二步:键入:mex *.c+ n$ z9 i2 z1 K, O5 x0 e7 U7 Z9 h
" ~9 Z' h+ L7 o; F" ]3 R*********************************************************************************************************************************************, U1 P( O- e6 E/ A/ h
# ~6 K6 Y; n& L L8 r' v# N
实例介绍:【转】
9 x' F. h- `! z+ |' k% |# F
( C( A9 C0 D1 S( B' c如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:3 E# W+ o* o' O5 g7 f% a
double add(double x, double y) {2 u+ }! S: g. `' z
return x + y;# [/ k, G3 F( c8 g3 p
}
. ~) a) a5 q5 _, H现在我想要在Matlab中使用它,比如输入:0 g1 N( C3 }6 L
>> a = add(1.1, 2.2)& m0 d6 J$ P, [7 H$ O, [
3.30009 B5 q$ J4 l( c% C
要得出以上的结果,那应该怎样做呢?, N% ]+ _- X' g Q0 Y! o
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。* M4 E: _$ K8 O6 f, }; W/ |8 w' ^
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
& q, U# d! X( U! X所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。; j/ n8 J [% z! G0 K S
比如该C文件已写好,名为add.c。那么在Matlab中,输入:$ W( O) r0 F% [
>> mex add.c
1 ?3 ?2 L y) E. f就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
% o& I+ o* d( O+ \, @我们现在来说mexFunction怎样写。
$ W! ~: O3 G4 gmexFunction的定义为:
4 c% q' ?$ N, H& ^) Q$ m' s# {2 x uvoid mexFunction(
- `5 `! c: W! i int nlhs,
, }% m: f1 m( ` mxArray *plhs[],/ g1 o- c5 r" v* s( |4 X
int nrhs,) y! N* `1 \: o3 V) r: w1 l
const mxArray *prhs[]) {0 D- h7 V2 J0 V
/ ^- Y% ]- }2 O0 z- }/ _: @
}
~) O; D. ?; b }2 i8 ?3 E! C可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
4 v: V0 W5 t+ O8 H0 A6 x- Z! p# b>> b = 1.1; c = 2.2;
" @0 S4 ~$ X7 T" u% X& e1 H>> a = add(b, c)
+ B# T& X. i' hmexFunction四个参数的意思为:) o6 m7 `" x0 d. V5 K9 ?
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
# B5 j+ x; y5 R/ Q+ u" C. r0 z+ unrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。+ V! R+ {5 |3 {" q, p8 X
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
8 u5 p# T* t- `prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
( k$ h9 T% r% N" @* q因为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类型的指针数组。. I' P9 M6 d; ^. M2 q* z3 E
完整的add.c如下:
2 V7 C/ P' K* N// add.c0 n. G4 r' j1 U4 J
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数2 C# p8 t8 x, ~" y6 H2 p
double add(double x, double y) {
$ S$ {7 m& j! ^ return x + y;
& r, G/ h5 W3 ~3 h} // MEX文件接口函数* O6 @7 C. _' a0 o- I
void mexFunction(
# `. k. y% o0 ^# D$ j5 o# h int nlhs,
; ]& [; `' w% U: g- N3 s mxArray *plhs[],
$ m' q8 p5 K3 }6 N& m: M. K int nrhs,1 w' I4 M$ \* \! S2 U+ Q/ h
const mxArray *prhs[]) {
/ K" X Y4 X+ e" t" J6 h# i7 j: O double *a;
: I, n: F( y3 t! O7 @+ O' O7 N3 Z+ _7 D double b, c;. {" |$ O& O: ]$ z3 |+ l
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);; u" L) S; g$ {! w# D+ B2 E% Z
a = mxGetPr(plhs[0]);# D! o1 p' S3 I( e6 K, l8 c2 A) M) R
b = *(mxGetPr(prhs[0]));3 D' q Y/ r G8 U F( Q1 B& L
c = *(mxGetPr(prhs[1]));
8 D( c3 M, n' E5 H *a = add(b, c);& M$ `( _9 v+ H. j5 A! C
}
4 P/ M, s- f" b @ P! ^# z" RmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:4 v; k0 S: j2 y, Y+ C* R. E5 s
>> output = add(1.1, 2.2);
% f) f# ]. s7 T& ^6 v k在未涉及具体的计算时,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便是已计算好的结果了。/ I# V5 i% `$ A( R, n
上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。9 L! X( ]1 ^1 u8 e9 }7 a. T
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
* R( T |# ^; ^- L' X输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
- ]3 r5 e' ]4 T9 }+ K从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。7 Z9 c% U0 q1 J
* g4 v, J, v# Y7 D
*********************************************************************************************************************************************
5 c+ w3 p! F7 R. C5 h0 e) I7 w5 q% l/ F& c3 E
mex 的目的,( Z0 |3 K9 c# d
# n8 E2 {/ c, I. d7 R' u! {通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:/ ^9 @' Y+ A, ~: u. X' o
7 D" j! T7 h# E W- f/ ]1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
; e; U9 l2 X3 S: l8 t- d7 [# c
x g* k; K3 n9 x+ O5 W2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
" D' @: G6 F# w5 } r' f& G0 S. k- G$ c6 G7 t4 y9 @
3、据称可以弥补Matlab硬件设备接口的薄弱环节.
( L; v4 W/ u" b# q9 I# \. E2 O: Y6 K! I8 E- `
今天写了第一个使用MEX.
1 M. s7 X, ^. a G; ~
2 F2 o! f* d0 c" N/ F" Z+ w$ `+ `- [一个简单的对Matlab普通数值矩阵的操作.
, c& ]% I, Z* U. o; \9 B/ A* h4 a/ f& w$ ~( M! X" W) ]
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
- l& [, s0 P& [: n$ S6 q2 m* J+ N8 ~9 v! G
一律用int代替.6 |3 r* a* U/ Y" e
2 f7 Q* i/ ?! @2 n5 g
#include "mex.h"
7 F% N4 X/ H0 Q#include <iostream>, T* N: T6 F3 ~/ x! P! g
/ o% H) K" L* p4 {
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
! ?- [5 E; }' G: M8 n{
6 U2 T& ~* `$ ~7 i& t4 p4 N- j1 X( N1 _
int i,j,k;
$ `$ {( Y$ T" zint index;
- I4 B! g5 X' ?8 J' m y: odouble* pr=NULL; A, ?# x, S' L- G$ i q
double* pi=NULL;7 w2 P& L J( W3 b
int M,N;
) D' u9 m. {$ vint ndim;
! b- v' s# H3 g9 q8 V; Cint dims[2];
4 L3 R$ P9 J% m* m* ifor (i=0;i<nrhs;i++)
- t: k/ b- I0 S* m# T# o1 T{
+ ~& g# K0 v2 y& N) G2 y3 w if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
" l8 N7 D$ ^! ?: U \, A1 ~ {+ ]( _' O9 [! J& @
pr=mxGetPr(prhs);. ~/ z! R* n6 z! l
pi=mxGetPi(prhs);
: C- i# {) j7 l- c5 Z* o M=mxGetM(prhs);
& q+ k; m0 Z; t3 x6 R N=mxGetN(prhs);
* ]4 B, [& F+ h7 a2 O. Q% ? ndim=mxGetNumberOfDimensions(prhs);
* m: b9 u$ f! G4 ~6 N: f) Z3 x" I; Z, a$ k Y& v0 j
mexPrintf("变量%d:\n",i);
9 B0 C( ]9 N) J for (j=0;j<M;j++) ^) e, {$ }7 h) i! w
{. m% T' @5 X/ d8 [* D
dims[0]=j;
, j/ ~6 P$ O+ c- U* l6 G for (k=0;k<N;k++)5 K/ J- q5 m5 z
{$ d4 y1 u G. [( s$ s
dims[1]=k;
' C6 }: Y/ I: i' i index=mxCalcSingleSubscript(prhs,ndim,dims);6 `+ J- Q. O- o4 p: T! o
if (pi==NULL)4 F0 p6 S k' Y# y2 ?2 Y
{
( `# u$ r% p) n/ b: h mexPrintf("%6.2f",pr[index]);( S0 m8 y. n4 P @1 x E% d
}
& x5 Q& ^5 N# e, e else{
, r9 }, t! ~! i8 ] mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
3 V3 j. s2 M. e& L1 V" y' c }2 [5 N2 [8 Z R( O5 G
}; }0 O; Z! g: r6 Q w3 G: A5 H6 m1 n
mexPrintf("\n");
! C# l f' T8 b; K0 Q
2 C" A! l8 h T* x2 X }3 }6 q5 O9 [* p* }; p
9 X4 s# v0 z) W6 D- I: L }
. o1 k: X) {8 \ else{3 z* p$ x8 r- ]& I
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
/ t f* n# H/ k}) ?+ p6 x$ U8 B' T2 \- x; T
& t, n) d. F7 ~
5 \$ r& j" C' K6 U6 Q1 w}
! r0 w7 u# R& j- c+ P& @- v. c% D) x+ k( h, I! e! {' w. |& {' f
}* R$ j7 M: S: c7 ? E4 K
% x5 s U: S1 R* M6 O
Result:6 U$ R# V2 N6 r9 o6 C% g, ~1 `( R8 A
7 }0 G/ B2 s0 F/ A* ?: r/ Y>>mex test.cpp( u9 T; V2 x6 O* {
>> test(a,b,c)$ u( [0 y5 |! O4 A& A- D4 x8 j) E) H
变量0:4 }1 Q4 B$ e: T( d) T. R2 K
0.35 0.62 0.83/ @3 i: r' F U3 |( z. h% K
0.20 0.47 0.59
) b& ^* r. d) h# b6 o0.25 0.35 0.55
& Q4 S/ i; o5 f变量1:* A' C5 E& e( z
0.92 0.38 0.53 0.57
' q+ w: [ k$ H$ l1 w% Z0.29 0.57 0.78 0.47
9 D: J1 B# i3 t# r; R3 \6 k0.76 0.08 0.93 0.01& u* V- ]- e( U0 d4 A
0.75 0.05 0.13 0.347 e& B) g* r$ e2 n
变量2:
, p3 e/ c, C. e R8 `; ~0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j* P% l% i. X$ F! _$ V K
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
% ?1 m3 U2 Q( X2 P( o0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
& ?" {$ V+ `8 y( H; g0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
" L6 D8 S% S/ R6 c3 E0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
; |' p2 D% H' f: c+ r$ T>> help test% l) n @% k o1 _3 d* G4 |
本程序用于调试mx______函数.5 u# @2 x+ _/ Y. Y8 N
, J# C- O% V2 X- u
$ }' P) X; u; x E6 ?% |, N0 n' o本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html
: d+ [' X6 t0 f1 s7 P' Z1 \1 E; r1 q6 P! B N
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|