- 在线时间
- 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年数学建模国赛备 |
. z+ S( d; j/ m* B3 t
Matlab调用c程序9 ]+ x5 u8 z+ n7 }7 e$ f4 O
文章来源:不详 作者:佚名
% ]$ H$ m( o' _8 H
) U4 N; I3 R) B; }9 }% c--------------------------------------------------------------------------------* M; j9 z; W3 h! S1 E
) g2 B. a, T) I7 ], N) T5 Q& a
该文章讲述了Matlab调用c程序.' h, {2 l+ G" V
- R' O( b* z5 K; Q$ q# `& o' @
方法:
/ a$ w4 E* V+ Q; E6 ^第一步:要先在matlab中安装c程序编译器,步骤如下:
' F6 }+ k: b" B4 ?. g键入命令:mex -setup;$ S6 F& H3 F7 [; O; N& [. l. D6 Z' m
选择c/c++编译器;7 _- c6 m5 t# \# K- r/ f1 o. r8 I* ^
选择c/c++编译器版本;
0 m# r3 C; B7 t6 w. h确认。
$ H( T" y( [" j" q! M( C$ q) B+ W9 D第二步:键入:mex *.c% ^7 h) w# O, ~! A9 W; q
; J. z9 K- f5 h1 w
*********************************************************************************************************************************************
, C$ b. F. V8 \% o0 T" U
2 Z% \( s/ Z# |, |: V实例介绍:【转】5 B7 r; m# J0 k9 Q/ W0 O' z9 @7 h
7 b0 [3 Y5 Q: E9 N' X' V" c% J8 B0 @
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
5 ~: Y. @! F, D$ ~' { ndouble add(double x, double y) {7 s$ F$ ~1 X# l
return x + y;
' N1 `- @% P9 Y3 O) _}6 U5 _+ w3 {9 ]2 C
现在我想要在Matlab中使用它,比如输入:
# w: b* d9 N; y/ f>> a = add(1.1, 2.2)8 x0 q1 F* ^! G8 x$ d
3.3000
" Q6 i- V( E! Z; n2 `& f1 ^# M要得出以上的结果,那应该怎样做呢?, E% e2 ~8 F8 i' T* W h
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。1 r$ ~; ^3 C/ k' r9 K+ ~- b
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
: Z/ N @: ^: U4 q所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。& S* x+ ?7 J) K! g
比如该C文件已写好,名为add.c。那么在Matlab中,输入:
# I2 @% ~- w+ g4 p% I>> mex add.c+ O: d& s: c- T8 Z1 J1 C
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
) J& w( M. d& h' _/ d# o9 R我们现在来说mexFunction怎样写。
/ a8 E9 g9 m" N7 C6 R) `mexFunction的定义为:" M8 b& w' s& M \& I2 `
void mexFunction(
+ @# |( ~1 z% H7 p1 ~) } int nlhs,# f& f" ?7 r9 _0 y, Y6 J, G
mxArray *plhs[],7 @4 y& P. ^8 c0 V
int nrhs,
1 w* V1 ~& _7 L6 g$ S; q& B const mxArray *prhs[]) {
8 N8 W4 t7 a2 h: \* o& J L7 m. V6 j: L' r1 f, A% [ \+ ]
}/ q! {: g! X" M6 Q$ a
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:+ ?$ |0 J3 R8 j) c3 G
>> b = 1.1; c = 2.2;
* f9 E+ D: |0 S>> a = add(b, c)! T/ X% Z2 h: P
mexFunction四个参数的意思为:- x! h0 j8 J1 q8 Z
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
# z, r! a8 q8 I/ a: Cnrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
$ h% ~4 R0 S, x* r# W3 A$ M0 }plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
' t; i+ |/ N% Q" v# F) Y% R; M- Rprhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。7 K3 G3 r' P [1 \6 a; Y' T
因为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类型的指针数组。0 B5 c5 G, T+ s0 t& T5 U8 n3 H5 e
完整的add.c如下:
0 E& q+ n9 r" f// add.c) Q( a+ Q* N3 W. c
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
' i# T5 {+ O9 c: C' qdouble add(double x, double y) {
x# E) G' v% f& h return x + y;
- a7 |. x: k# Z0 D' ~1 ^} // MEX文件接口函数
9 m/ }& t5 v H- \void mexFunction(
, t5 l, K8 B4 G: S int nlhs,
, K1 y/ _# c+ E# H0 k# x- e mxArray *plhs[],
, S8 c* c7 f* K" i int nrhs,. v0 w6 g9 ~ n4 v7 L4 \
const mxArray *prhs[]) {8 V) ]7 ^0 _) c9 l3 I
double *a;7 P8 e3 v' G! J5 p
double b, c;
% ~$ x$ g# M. D: R plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
9 s$ T; f8 o$ K4 m a = mxGetPr(plhs[0]); l' @6 g2 b- V, K+ I0 w/ z
b = *(mxGetPr(prhs[0]));& i& V7 c2 U# l0 b3 T
c = *(mxGetPr(prhs[1]));7 u2 [5 j# m2 n0 G9 h+ f
*a = add(b, c);3 g, s. p3 ]' H4 S
} 4 z% B6 O& [& O" l. |9 A) ]
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
( p; d! s# {3 p7 n9 J- G# j' d/ H P>> output = add(1.1, 2.2);
2 r# g. }- T# q: a8 [0 H在未涉及具体的计算时,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便是已计算好的结果了。
" I0 N0 _( q- g* ^4 i0 d, {上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。) J! o( B/ Y- H. B
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
u. S* p* |% z8 z) a, N/ N输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
3 T& p' z( u8 g+ x# V% h从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。+ M+ N- f" @4 P1 |% ]6 C) A
) Y% T" j& h5 q1 ]# E
*********************************************************************************************************************************************+ \- c; _& Q; C
! |. S2 l1 t) c3 z3 w/ y' |mex 的目的,, Y: m- `; B# @8 W y
* i- f5 a1 T* Z" ^1 o" f, c$ {
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:
) }: F- A4 k) U4 n% [4 z2 G' P( K: d" T
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.* U- q& g1 U S- s; ^
( V9 h' S" w) x3 l, m+ ?2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
! ]/ x6 n0 \' N) I: J; L; G4 N& X3 \( N8 L3 Y/ Z( Z5 y$ [
3、据称可以弥补Matlab硬件设备接口的薄弱环节.
F5 m. o5 J. H# ~( x, g5 Q8 @$ {0 f* r) ^. k6 X
今天写了第一个使用MEX.
5 \4 l) p0 D# i7 k2 E& j y! f, T) a! E4 V0 Z g$ I% G7 V
一个简单的对Matlab普通数值矩阵的操作.
# T* y6 y1 V) N* ]6 f: p- F) O- o: V) M$ F7 d7 ]
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
2 T) x) x5 ?& G" {/ M$ S
O2 O2 L4 M$ g% s0 G+ y一律用int代替.
. X3 c: a. [$ G5 H9 Q. M$ |
; [5 s! _& W. d( B$ A#include "mex.h"
9 P3 r h: m( f. O+ v#include <iostream>
5 b" n! W4 e* l7 G
6 z$ }8 R/ x2 L7 e6 Q$ Ovoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
- z1 T* b: T0 |3 ^+ P C{% Q/ i! [, X8 M2 m' U
) N$ ]! r$ `( R# M( j x- G
int i,j,k;
3 u7 D' o, b" M/ n4 Lint index;. g& Y+ O8 }. S7 \1 q# h5 h& G
double* pr=NULL;% J) p) H( v2 g) s5 X8 w2 n4 ?
double* pi=NULL;
, l$ a% ^* V0 q- m) hint M,N;
, o C# l# S6 _$ N6 K* l' w9 Dint ndim;) N) U0 `0 T9 A3 j7 \/ V
int dims[2];+ R7 n7 C8 \6 x0 z8 G4 F' [' s
for (i=0;i<nrhs;i++)
. v o' p# t8 A( ]+ ]2 n{
1 R# b' X1 X" p0 B( M if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))" j8 @+ u* c3 K7 v$ ~
{
! {4 l1 h8 W) L# C" q pr=mxGetPr(prhs);
0 w6 W3 `" b. C% t: r pi=mxGetPi(prhs);8 B5 H$ i" F# p$ Y; U. b# u
M=mxGetM(prhs);$ t* V" b# D; X, V
N=mxGetN(prhs);7 a$ M; M6 {5 K, N$ h1 q
ndim=mxGetNumberOfDimensions(prhs);0 D2 \' C+ Y7 _- N
& F) U) L; |+ M/ K mexPrintf("变量%d:\n",i);0 r5 N' S9 I2 j- \9 @: V
for (j=0;j<M;j++)# O& B! }3 B0 y4 s
{
$ ~/ P, @, J- Q+ L1 b dims[0]=j;! m' |8 [# V& O9 ]2 n2 |5 v; g$ b
for (k=0;k<N;k++)! j( R4 P1 Z) `7 G. z, U
{
}+ n8 g4 C$ B4 u+ J5 ~( g7 c4 j dims[1]=k;
# n/ j9 C. g7 R) k8 R' W# V index=mxCalcSingleSubscript(prhs,ndim,dims);
$ d O8 t! Q4 x7 J if (pi==NULL), V$ m l1 h2 T; `1 n; h! j7 L) ?4 @; p
{
6 X% \5 ~9 G$ _7 c mexPrintf("%6.2f",pr[index]);) p( [7 i% a" d7 N2 T7 X
}. j& F4 R# Y7 b+ A, K- i- P# |* |9 b }
else{
3 `, O; v" m4 E! n mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);$ Z4 B# m: H3 L+ C% L2 j8 }
}
& X( s7 S; H: a }6 Y5 Q3 j8 _& A6 y q+ j
mexPrintf("\n");
7 A+ E6 w7 n1 {% W4 ?( E5 m1 k% n- @. j8 v" n
}
^( z v6 O4 m. ?8 k) N
# {$ `: n9 T q' o5 o0 n }2 R* I& i0 [; _0 P1 X$ \
else{ s1 k2 Y% u% Z2 `$ O/ s
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);/ I" I) z: \( D2 d: b9 }3 J% N
}1 n& K, X( @/ S6 ~- V" b E A
6 G9 l2 {: ?" t% @6 u8 w+ K
! `0 x5 D8 T$ A! Z( M
}
) n5 C' r' l8 B' J& Q0 H Y' ] c* @8 Z
}. y* D0 A) s* @9 G2 L. o. v7 b
. | b- v7 V' |9 A: i9 N& G% J
Result:8 d+ o1 s) `1 ?. u5 }' `; r% }
# }. X. I/ D0 [
>>mex test.cpp9 O* V$ ~" `$ v4 X( j' D2 C1 B
>> test(a,b,c)
' V( B& Z0 e4 K, M' \, p变量0:+ ]% ]3 D/ J# ?( P! p
0.35 0.62 0.83
3 ~4 g2 P7 h! D& p+ |) Y0.20 0.47 0.59
' _* s& ~) S$ w0.25 0.35 0.55
; B5 S' z/ f! Z9 U c5 U) V变量1:
( G9 w# {6 y+ c; [7 q7 a2 q9 G- \1 Z$ W0.92 0.38 0.53 0.57
5 B; x( I8 h0 B9 w$ y4 j: L8 c0.29 0.57 0.78 0.47
/ A2 g' K$ @+ y! m4 @3 z0.76 0.08 0.93 0.01# F& j1 w$ W" K' M
0.75 0.05 0.13 0.349 {) d2 {% e. @. N$ T: M
变量2:$ a; ]. P4 W6 \
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j- M3 F( p, W9 L% k
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j$ i& f0 K- `! ^+ v y) `- C
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j4 ? p. |- X% _3 y/ M. J9 N
0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j$ ]9 b8 V0 f. T9 k- U( P
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j! E) ^! q& X$ R: C0 ^! ?8 z! U& n
>> help test/ ^6 `9 c4 ]8 D$ f; C: `3 z
本程序用于调试mx______函数.- n" x2 J' Z& O) C% J
& c: q& [9 c+ q$ u/ R$ d0 d
; l$ `3 }0 m7 Y2 Q; Y/ h% q
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html
1 N$ b |" |1 d2 H7 t* f- Y: ]5 X1 _. T @% d
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|