- 在线时间
- 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年数学建模国赛备 |
- r L! q0 e7 JMatlab调用c程序$ @8 a8 c6 Q" d Q7 r& Q
文章来源:不详 作者:佚名
2 r& }. v/ a+ A, ^9 m% o
; ]; y2 A! \/ Q( q( f1 ~--------------------------------------------------------------------------------
0 w* c/ ]; ~) h
; h9 i9 W; `- y X8 `7 `该文章讲述了Matlab调用c程序.
8 A) Y9 w4 _" ]' J& O
5 O9 H5 `6 ^8 [; G4 q" T. @' m方法:
8 _. R, P2 Q0 |( N& c, N/ _% j第一步:要先在matlab中安装c程序编译器,步骤如下:
0 ?% }9 q4 v0 o! W& p1 u键入命令:mex -setup;6 {0 w }; A$ f' [6 ^
选择c/c++编译器;
, d" U4 }) K, N% ]) S选择c/c++编译器版本;
# o: V# Y. y- y. Q7 w2 o确认。
- C. v6 k" d* Y/ `9 R3 ]第二步:键入:mex *.c# z! N9 Z4 ?) o$ |0 X. |
7 w: n! q0 r5 x9 p/ F( H*********************************************************************************************************************************************
6 L! S8 C1 T @/ |7 f! X; g
4 I6 N! w1 }( ^* \0 Q, c4 e. A实例介绍:【转】9 D/ n: z! a6 L. n, b2 Y
: L, m2 [ X7 `4 _2 L
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:4 s2 A7 r- f$ s. n4 p( j
double add(double x, double y) {9 `0 A! D% v% N
return x + y;& h) l1 E$ f H
}
" v$ y$ I* k D2 j) C现在我想要在Matlab中使用它,比如输入:
( O. t* _" z! W>> a = add(1.1, 2.2)! m$ p- I7 N6 t& i& ~3 r4 m
3.3000" L0 {4 k% j( }$ v
要得出以上的结果,那应该怎样做呢?( E) `2 Y2 x( H& b4 I1 Y
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
1 {* B. c2 T$ m: j+ B1 z+ g" v/ E可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
" U: @2 |/ j% k) l所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。0 w+ z! B5 s& B; B
比如该C文件已写好,名为add.c。那么在Matlab中,输入:. p/ h* b* v r# P: ^1 Z
>> mex add.c: E: j) A9 n: V
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
5 u" P3 Z2 p5 e! _( Q: l我们现在来说mexFunction怎样写。
8 m0 m$ x2 c0 r2 p- e! y0 ] gmexFunction的定义为:
! n6 U0 o/ h+ ^7 Fvoid mexFunction(
2 y) F5 u( g7 I, T int nlhs,
8 i; }) B j7 r mxArray *plhs[],
4 F/ A4 o0 Z5 u- o int nrhs,
6 ~9 J+ t: w, [/ g6 B const mxArray *prhs[]) {
* R. ]2 f$ I$ A" X* E
0 {# C. u" D% E# N( f3 ?8 y# R9 Q! k}! b* w; \$ I: `: W! f% d/ @) n" q
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:9 [/ c, C, Q1 w9 I8 ?; V
>> b = 1.1; c = 2.2;3 s+ M5 Z" N$ Y5 ^3 k7 K
>> a = add(b, c)9 U9 w! Q# ~2 B, f
mexFunction四个参数的意思为:4 h8 t8 V, J/ a! b1 T% ?+ j
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
1 n+ ]! f+ e. }nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。3 N% t. u# P P% l
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。. _+ T0 b7 D7 g2 [9 p4 v2 |
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
+ s; [& @: |; D; Z因为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类型的指针数组。
' k1 K5 i2 x6 G5 M8 A' H完整的add.c如下:7 y2 |9 r# o1 t- A
// add.c) u4 n8 K+ l9 |! h+ k( u
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数6 d9 R0 R+ z3 a: U, M5 g/ ^
double add(double x, double y) {" f9 c* v p. G6 n. c" A! l
return x + y;
+ O3 q/ E+ H* W1 x} // MEX文件接口函数
9 z0 [/ l' F- U( I* K" Wvoid mexFunction(
% e4 L# s& n1 N! ?' f int nlhs,
1 Y0 }" @0 ^2 R) o4 w/ L+ X mxArray *plhs[],
{: W2 `2 `3 [( q. M0 D7 ~0 T int nrhs,( N4 l+ }+ `, P' G1 u0 d* q7 r
const mxArray *prhs[]) {
* V" Y3 Z. K+ N( L. z. |, t" t; r0 A$ U double *a;
7 Y9 {# I$ e' C6 R \: w double b, c;
" S, `# w( D" j) V2 d plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);5 q3 j/ _0 ^% K% V# ]& o
a = mxGetPr(plhs[0]);7 c6 G# h) P: a/ e' Y
b = *(mxGetPr(prhs[0]));
8 F, y$ r2 I( V/ o c = *(mxGetPr(prhs[1])); H: X' @3 r, H
*a = add(b, c);
U% Y s2 U# L# G1 z" G} 9 ?% X" w# Z* c X) j' G
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:, A" o7 M- Q$ k4 c: L- [# v6 U* Z
>> output = add(1.1, 2.2);
1 b2 V) F9 [2 ~: P) f# Y/ s在未涉及具体的计算时,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便是已计算好的结果了。
; ^1 _3 R3 p! K6 P, |: C上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。# n: [/ d" i, ~
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保5 u3 _ h# x3 u% ?. ?
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
8 n& U. D; H$ j从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
- P) K: b- n# Z& ^( {8 L* e
( P. B2 T1 O1 ~: C9 s5 |*********************************************************************************************************************************************
' w n( \; N6 n0 ~; t, {! B9 g B7 S. s% G0 E9 k) k
mex 的目的,- `' O2 _& }$ C/ S4 i
* N n) j0 y' K! W1 C' V通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:, C9 ]) a5 }3 n# T
' b0 M/ N9 p' M- G! S y# B1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
5 H% ^( Z) L, Y3 w; w: C* ~! v. h# O. Q8 Y* z
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便., L$ h, z5 Y+ r
+ Z7 I2 t' |5 j) v3 c3、据称可以弥补Matlab硬件设备接口的薄弱环节.3 U, _* l5 w8 _' E( {8 ]. H
. \0 }9 m* P# l$ B( O' m% ^3 ]
今天写了第一个使用MEX.8 w; S$ \* w, i! ^/ C
% O9 X# h! t8 v) z1 L6 I一个简单的对Matlab普通数值矩阵的操作.
) L9 W7 |( \2 U: u& j
) R; c/ k1 {8 i其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以5 n2 L5 n- ^/ N2 N: t
+ |% {. A' l6 y' j一律用int代替.$ ^9 O. d- Q. S1 F: Y8 v5 O1 [+ X/ m
3 h6 n. R* b: I8 s7 A#include "mex.h"
* j1 u& E% ]) X: G* k9 j4 k: [#include <iostream>$ s1 j6 ^9 t. e# l1 v+ N9 E% A
+ e& t' c0 b$ d! x6 j, _4 K7 Wvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
* C# S7 x& V# d4 z7 x; Z+ C+ @{6 u6 k4 j6 a+ \
# M# Z% P G# K! P' k/ A! Z7 w
int i,j,k;
: B6 P7 }" d* fint index;7 }1 D' K3 Z; f8 @' b
double* pr=NULL; W1 {, R1 i; W! g9 M" u' J! Q0 ~* @
double* pi=NULL;
" W3 W; D1 b& U& S6 Qint M,N;) c6 O+ C; ]7 \9 u# c4 t. A' x
int ndim;
/ ^" u2 f s; Yint dims[2];
) @$ f9 ?7 g2 x' yfor (i=0;i<nrhs;i++)
% D2 ?/ n" m; q1 i; q" n) E; G{: O( b7 ^: u" N3 |! h# W# v( U
if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))1 F, H/ ^2 B; V1 m7 H! {
{5 u" [2 C# l) j$ T# T
pr=mxGetPr(prhs);" H6 c$ M |9 |7 P u9 Y- Y/ Y
pi=mxGetPi(prhs);
+ O. C2 m, C. o3 m M=mxGetM(prhs);/ v! \ A. p. h; A
N=mxGetN(prhs);
1 B8 w$ V; j) G' s6 f; Q$ O+ } ndim=mxGetNumberOfDimensions(prhs);4 r; c' j/ @7 _* {) a6 f" V" N0 u% Y
. q9 k, g; w- m. o5 m$ X mexPrintf("变量%d:\n",i);
$ N1 ^9 K) V$ ^% B6 ^5 O for (j=0;j<M;j++)
' M) q$ @1 \' _& @0 T% F) F$ t( V {) r* P) p6 l6 n9 I6 ]. U% W
dims[0]=j;
4 F' U: V0 ~) T: m. K/ ]3 p for (k=0;k<N;k++)" P, ]9 q1 o* w, T
{: ]% _& J/ U: ~. M. x% J
dims[1]=k;* R; K3 i5 L* M" {
index=mxCalcSingleSubscript(prhs,ndim,dims);4 X3 D$ h @) p+ V r$ l+ e
if (pi==NULL)
# Y9 F3 |& l7 q( e/ C( m7 Y {
1 |" A" N$ o" J6 Q6 H mexPrintf("%6.2f",pr[index]);1 {8 A- B, n7 e# d
}9 y5 @" D5 B# a8 L5 D% _
else{2 S. M8 f9 V( w: O, Z
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);4 E5 D2 m! x& ?4 X: ?2 i3 z4 R: |
}# ?6 }7 {" v n1 F9 E- {
} e+ [* [0 e4 _* D& c7 Q
mexPrintf("\n");
& Z% }# x, e8 L& Z6 X. I, c. O6 y3 R
}
( F* H, b- v- ]5 o# B5 m
; O5 U/ i' v X8 D7 I' N$ x }3 ~5 r0 c- B- [5 ~% I& e; t
else{* F9 Y2 r+ {; S/ Y% Q1 Z* n
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
# i7 d( i2 o Q; o}
7 Q ~# U' [7 K& A5 Q% V
" O. p5 Q$ j4 r+ i
. C; N7 n& r b2 V h9 ?}
: r9 _. R3 w5 G6 P& v- F2 v: A. P& W( n5 ^5 p
}
3 z5 b- ?+ v0 l5 r2 T) }% h+ F: c9 I; G. X
Result:
+ Z/ U, x$ p5 s- h( ^. ]. j& B. M1 B- u+ n. X: S) f7 I+ ?
>>mex test.cpp
% Q( [# U6 X8 ]% c& x& a>> test(a,b,c)
/ i. |/ e1 U/ x. Q变量0:+ J( C1 Y+ z0 p' J& C! _# S
0.35 0.62 0.837 K5 K2 q, K3 W
0.20 0.47 0.59
; h+ @% O- T4 k. ?+ c* o0.25 0.35 0.559 Q% h, v! G7 M, X( Q X
变量1:, Y8 F+ m. |7 c% b u
0.92 0.38 0.53 0.57
* S1 W% F8 C, p* H% u3 m( k0.29 0.57 0.78 0.47
7 ?, p2 s3 H7 W8 R5 ?0.76 0.08 0.93 0.01( V4 p! M; ?- S
0.75 0.05 0.13 0.348 u6 U. {6 D! v# q' i
变量2:, X4 d) l2 A. m7 ]4 l
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j* n0 N6 @ q" v$ d
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
# ]$ k3 q1 d) a! R; O, _0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j5 }% _3 @1 K( p
0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
' I5 h' N d& ~& C$ h8 ^& {0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j( l+ R+ ~- A! l9 Q7 S! E' q: F
>> help test0 H N- h( u5 K% [
本程序用于调试mx______函数.
& h+ H7 ^4 @# m, ~
# ^* a8 k- g0 J5 D# P* B* E0 y o1 T. W% [$ n
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html
7 f1 z7 s- `" h/ {2 y" a$ R# W9 g( ^
2 G6 u _5 `. Z' o下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|