- 在线时间
- 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年数学建模国赛备 |
2 z. I; [. W6 w8 YMatlab调用c程序& m, b6 V$ ?7 _5 J1 e+ [# `
文章来源:不详 作者:佚名
8 b; ^0 y5 w7 r$ W
8 _+ E+ V, R+ z7 |) I2 B9 V--------------------------------------------------------------------------------& [) |; Q+ B3 F; [# i6 d- _
5 g. M" @' Q+ k/ q( K* Q
该文章讲述了Matlab调用c程序.' Q0 M$ j7 o6 }2 ?
4 w, i( y- y* `! @+ o( C6 [
方法:
' x0 _' \2 p4 ~7 Z ?0 s/ |第一步:要先在matlab中安装c程序编译器,步骤如下:
3 v1 {6 f, B2 ~- F5 p$ W- Q键入命令:mex -setup;
9 \3 M. ^2 k% m* ?选择c/c++编译器;8 C! }. o; e6 d* n( u9 _
选择c/c++编译器版本;
" c; l- @( Q' d0 j: U确认。, I' V' }1 X* V# I0 v1 L, v
第二步:键入:mex *.c
' n2 u# O1 Z/ Q2 ]) e; u; c2 V8 K' ?9 o3 v2 D, p1 C. y
*********************************************************************************************************************************************: M4 z9 X. |" C/ `7 I$ Q, T
: V/ U4 y: y+ e9 Z. \
实例介绍:【转】: j, K& ?+ H; _# |4 I6 g: B1 t
( W" M2 H. w2 W# Q! @
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
# m& v( P6 x! C# ?% Q3 L) Zdouble add(double x, double y) {
5 Y. w2 D" o' @" s- S: R4 l return x + y;; Q' Z3 H }3 ~& P" ] i; b
}
9 N$ {/ U( a% ^ o现在我想要在Matlab中使用它,比如输入:
& X0 p) r4 g* n, I* e, F2 I>> a = add(1.1, 2.2): U5 Z+ _" |8 w4 \
3.3000# @' i# ~" v' R* I# B; \
要得出以上的结果,那应该怎样做呢?+ {7 ?, n+ b1 G' T: [9 c' Y% \& `6 n
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。2 M7 O6 r4 v* J' }2 q, E4 r- I
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。# ~+ n+ D; X: `; B+ q0 `
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
6 X7 _" O1 W) I; I0 V& S( n& C0 e O: @比如该C文件已写好,名为add.c。那么在Matlab中,输入:9 N' L+ ]4 j9 u: y; V$ Q, a
>> mex add.c
. `2 _* N; M, Q; c! n) T0 {$ }就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。2 }! w# l' g6 P, D7 J' u
我们现在来说mexFunction怎样写。# x0 Z% G; a! p; [! W4 N* P: s; }
mexFunction的定义为:! M$ x0 H6 g$ s% ^; S
void mexFunction(
+ K3 H3 c3 m* T2 p0 @/ x; E4 h int nlhs,* O0 V# H1 a- o' W: z; w/ M
mxArray *plhs[],: n F3 I# o( s1 P& u
int nrhs,7 N! p/ y- a) G; A# E6 K
const mxArray *prhs[]) {/ m- B+ F9 U7 b' z' c9 M
, D$ C* b3 b2 M+ q( ^. K}) Z3 ]1 Y7 l+ E! r- b" d
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
# ^9 `5 W% a( C9 V: ?>> b = 1.1; c = 2.2;+ K f! E% t% [+ W+ [3 h" K9 h
>> a = add(b, c)4 k% k$ I9 t3 T
mexFunction四个参数的意思为:
) Z( e2 e( \! U6 Cnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
8 k' @6 N! | B) H, f! N( E h) Hnrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。, m: V( N# R7 j
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。# T+ q. |2 o, u5 H6 Q9 u6 H
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
# e( P- Z6 l, _) g因为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类型的指针数组。) l `3 v7 E# H, V2 R5 Z
完整的add.c如下:' D* ~' g) Z/ c, I7 e
// add.c5 ]$ H, y& S# Z6 j$ M# f& s
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数* X& b8 W; b/ b6 [( b* m! g& V! a( _
double add(double x, double y) {$ D- d {# n+ D$ J$ w9 L
return x + y;
3 j+ X' s4 C, e- F8 b. q K} // MEX文件接口函数
# l- v6 _: k4 z2 e# f+ g; @4 avoid mexFunction(1 ]' a2 d( v+ O! D1 {7 C2 ]
int nlhs,
C! _7 m' Z# _( ?1 h% y& R mxArray *plhs[],
3 F' b, B- ~3 m, ~ int nrhs,) S5 x4 {! i9 S
const mxArray *prhs[]) {% u1 F. {7 ?( f! P
double *a;
) ~$ G- J! M S, E+ | double b, c;
8 v9 _( [: u4 w3 f ~4 n, ? plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);7 a+ M' ? Q$ L+ A# n7 e
a = mxGetPr(plhs[0]);3 k; h# F. y# X+ J9 b- R8 l
b = *(mxGetPr(prhs[0]));, G: l E6 Q: E+ ] W# F! W
c = *(mxGetPr(prhs[1]));2 [& L& R+ b# | {/ O/ C! w
*a = add(b, c);! d& Y% U4 E8 c, X4 A3 q
}
% C( S8 Z1 D3 z x1 Z" EmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
8 d N+ ]# m( B8 ?/ A8 I7 |1 a>> output = add(1.1, 2.2);) P( q. L) a2 k6 K) E1 N
在未涉及具体的计算时,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便是已计算好的结果了。
# V1 i J5 z' F上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
1 w; c3 [4 b; I' l( I实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
/ r7 w9 i y6 T- Y: o5 f- `& B输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
R/ _4 _: e( g# Z& b从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。6 q4 X& m2 d+ D
+ ~/ }8 c/ O* k; P( f9 w*********************************************************************************************************************************************
5 w' P2 N$ O. |6 O W2 H8 Y% b: q" [0 q" |# V+ v
mex 的目的,8 s; V& x! B6 f$ F" f* e
7 Q! N5 M8 h+ K* Q6 y6 Z2 w
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:" l' s# ]* x' a3 I1 `8 n. m( Z
: w3 H( o9 \ k H* S* j2 z7 @ e
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
1 P; ~ R; [/ S' s) O; ^7 t7 O$ J$ y
( V! m) I- t4 e% x2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
% H( |3 N/ E8 _$ K
7 |! o5 ^% D @3、据称可以弥补Matlab硬件设备接口的薄弱环节.; }' Q- s: G, R" D; B" I) V. G- f
: h. A0 ]% s9 }- n9 b+ q今天写了第一个使用MEX.
+ x8 i3 ~6 i5 p7 F! x' f! c
2 s( Q o! p4 x9 y& I0 ~一个简单的对Matlab普通数值矩阵的操作.7 e( {4 ~) N- D
8 t6 o; {; P( H8 R/ u: r
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
+ w6 V5 C. ~5 h [& j2 Y0 a/ L
7 {, f+ e% Z7 z7 p一律用int代替.
5 z# N* I' v {/ D- D6 W( p& A- v0 a1 {6 Y/ J
#include "mex.h"
; z) f0 y' a" `#include <iostream>
) _2 h4 m4 |* G5 D5 z2 V4 \
9 X5 |. ^$ c! t, W* vvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])/ Q) T" y! D( @- J
{ O Q0 F, z; e/ D7 q
0 ?" T; C/ }, D6 f/ w& ~8 kint i,j,k;
& z5 @8 ~) x' Nint index;; _/ `. V0 M' d& i
double* pr=NULL;
6 K% [& W+ k1 b4 G; Q3 y ddouble* pi=NULL;0 d) n/ {, |' v3 j: P: T
int M,N;
& e1 u" ?# [: f* f6 D6 a" ^int ndim;6 L. d* l, i; K6 l
int dims[2];# i0 z& |5 }) K$ N/ K+ R+ g
for (i=0;i<nrhs;i++)
' ^6 K+ A4 `4 L& B7 Q1 A{
) P3 r/ f e. y- k1 E4 X' W' J if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2)): W- a" Z$ w. }& n2 K
{
$ T% {5 h2 r _ pr=mxGetPr(prhs);: ?% T/ Q) t$ T* g" u) j4 ^
pi=mxGetPi(prhs);: Z$ ~ L6 l" Y- ^9 A3 o
M=mxGetM(prhs);
- u3 C8 N, j6 N, C( X6 z N=mxGetN(prhs);0 {) s( s+ ?+ o# ]' Y9 @
ndim=mxGetNumberOfDimensions(prhs);5 L: u3 t. b% Y1 s- ]
U' k5 X! d) m4 E+ k
mexPrintf("变量%d:\n",i);
0 V' J. k/ Z3 o: V+ K0 A) h6 k for (j=0;j<M;j++)" R* F3 j2 v H
{1 G! w7 ~$ P5 L7 I6 l) N7 z+ \
dims[0]=j;# Z% X6 ?8 ?$ D M/ c
for (k=0;k<N;k++)
2 Q2 j) C/ \) }; o! F8 Z% r {
5 V. M+ E/ M W) c dims[1]=k;
4 S: G+ W/ c1 \7 m+ A index=mxCalcSingleSubscript(prhs,ndim,dims); Q1 g( y( r) M6 f0 y6 W. k, a& _
if (pi==NULL)6 z& q+ D3 y, Z& R$ U
{
$ D/ O$ m$ d) U mexPrintf("%6.2f",pr[index]);9 {% g( d9 b% p! L y' D( K
}
* Z+ k8 S- W7 j, {) b5 [+ Y else{, N& C4 S8 {5 |' g r
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);- f. I$ A0 E- |8 s3 y
}
8 K* ^& C5 l* s5 {4 M$ L0 d }
8 F2 F9 S4 j- ?/ n mexPrintf("\n");
) ?, x- d5 D4 D( _( |" \$ i
& v8 N: \! y7 @$ W" c, y) d }
* Z4 c# \4 X: ]
q! z/ Q1 u6 H6 L4 Z2 N }! Z; b6 ]2 S" n) a* i7 A( Q
else{8 Q0 k/ R* ^2 j' @
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);; ~; d5 c; e. u2 ^2 z; i
}2 a& @$ d8 f/ t& m; ]: N+ Z
X: u* F9 @( X# C4 u' @ x
1 X, ~) }# E0 M% i( t}
& y" ]: K( Y' n6 f3 {. d# }6 h6 \/ p! F. L! [* J" n
}
) n- l5 _" m: g% o: B, [4 ]$ X+ V0 |2 {
Result:2 j6 }( N1 \$ A! l0 e
2 X b/ Y) t! g; [6 l>>mex test.cpp( C! x- C0 X+ x* y2 R" E
>> test(a,b,c)
2 i5 M3 d, `* i- v$ q变量0:, }+ l2 E3 V) E2 e
0.35 0.62 0.83
: t" @, Y, ^: ~0.20 0.47 0.59
- W x; |! _( r0 N0.25 0.35 0.556 I7 d& q8 u. e5 p. i5 B3 H8 J
变量1:/ k8 ]$ e' ?3 v* x q2 r; C
0.92 0.38 0.53 0.57
, n2 ?+ M* H* A3 L0.29 0.57 0.78 0.47
?6 L; J5 _ s# }, _9 F b0.76 0.08 0.93 0.01
3 B+ O/ b) c+ J% Y+ z, Z1 Q/ J0.75 0.05 0.13 0.34
. A/ x0 w" L1 M: R4 v% |变量2:
2 | B. A$ j, I+ j9 e; a. V9 W+ N' _0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j+ u9 b; ]& ~0 e$ b5 j
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
) Y( f- F4 j5 o. ^* Z0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
- D3 {( [( f p ?0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j8 d# `! X! ^+ z/ R: W
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j2 m1 r: N# V& o# N' ]
>> help test/ \* G* L( T( g3 C
本程序用于调试mx______函数.
1 g2 R7 X' X8 |" m! [. @7 w7 c
) l3 B. K2 x T% l: _5 b$ h1 D2 f2 f, E- ^, P( b$ w
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html
7 A( v! h' S$ H2 T7 C
. [, ]* K2 c1 G2 l- A下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|