- 在线时间
- 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年数学建模国赛备 |
, W2 N! [0 D- L, b- z( P
Matlab调用c程序. ~" | g3 }8 q d5 k- z# v- d4 e; U; D
文章来源:不详 作者:佚名
0 p2 k6 R3 D6 T. k# V6 W# r5 C. U
--------------------------------------------------------------------------------
" z2 [, h) {; b
" j' {- ?" S6 y s6 x0 `0 P该文章讲述了Matlab调用c程序.3 z2 m# a( i+ R. ]
5 c' O6 t4 r# J% e2 u. O6 y' Z: M( n5 ^方法:
, g4 ?1 {& f* }. f' O o第一步:要先在matlab中安装c程序编译器,步骤如下:
) ?& [. Y9 W1 K/ d0 X, z键入命令:mex -setup;$ x- ~8 Q8 }. a. l7 |4 T. V7 U
选择c/c++编译器;0 v7 W( G* B; D" u$ C) Z" J5 X! v2 {$ P
选择c/c++编译器版本;
9 D; A6 z6 j. n5 a( }6 }3 K确认。
+ J" }5 V. R+ K' b/ V$ Q/ {第二步:键入:mex *.c+ n$ q' i! f& e/ e4 D. D
9 }3 V$ P' {2 S# W*********************************************************************************************************************************************
q6 h5 I V j
4 r2 v4 o2 M3 R" d实例介绍:【转】
, A; w, J3 x: ] s
+ p/ v- X# ?0 P3 N. E7 T3 @如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:9 t/ d4 [3 m, h5 y5 F* c
double add(double x, double y) {
# l+ U/ o0 t: o% n$ Q/ b return x + y;' b8 g& r$ p: q$ c7 J
}+ K6 r6 l3 c% R7 p3 `3 k
现在我想要在Matlab中使用它,比如输入:
o: ]' E; b5 Q" h: Z+ j# T>> a = add(1.1, 2.2)+ {. a y! i4 k! C/ y2 I9 ?
3.3000
$ @1 P% |) }, {* P) i要得出以上的结果,那应该怎样做呢?
" M E @' w4 o# P- ?: _解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
O. Z5 f! g1 H可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。; e' P% Q3 `9 x9 Q
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
! F# X& j: R6 ?/ @; \9 H比如该C文件已写好,名为add.c。那么在Matlab中,输入:9 S& @8 A- T# @+ ]3 ]
>> mex add.c3 m' n4 B1 i8 \* b3 [$ G/ q
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
& _% C2 ~' m7 T我们现在来说mexFunction怎样写。7 C3 S3 Z2 b3 ^; d
mexFunction的定义为:
0 T5 N( G" S$ u1 l0 r$ Qvoid mexFunction( j1 h7 i6 e8 L' U& I. _
int nlhs,' R; R1 l: T0 z# c
mxArray *plhs[],# U- S2 n' Q. R) c( }+ v* }5 \# N
int nrhs,* u7 x$ m. `1 h
const mxArray *prhs[]) {4 y8 h6 k- c7 C Q" }9 N
4 o1 Q, v0 N& P* E+ J/ Z
}! e$ U% T: h; h; Q( n
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
7 C# l& @/ T. s0 S5 [, D4 l>> b = 1.1; c = 2.2;/ P" ^ j6 ]8 z, o6 J, @7 B. k
>> a = add(b, c): G1 V4 h7 ^1 N1 `2 n+ C
mexFunction四个参数的意思为:7 T/ d! f2 S- x: Z8 V# F
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
+ U0 @; \! f! a: r4 t9 L* |nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
" N" v) I( |+ S0 l- P: Cplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。0 E' q; ?% {0 H
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
2 Q; ~' _. ^1 L& Y因为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类型的指针数组。
* h/ Y( p/ C# U7 Z: N2 @% w完整的add.c如下:
: ~: M, G: J% ^7 Q _* d6 e// add.c
0 o7 l* F/ `% |5 E& D3 I; O#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
3 w7 L3 u; w) Q8 w' z: s. N2 D3 G# mdouble add(double x, double y) {
) e! t' B( j" x$ m- e return x + y; g1 f( y/ l+ j
} // MEX文件接口函数$ ~5 G5 U& ^6 x$ x$ d/ v6 y- V
void mexFunction(5 ?9 g! _7 g; T3 G3 N0 j2 r
int nlhs,
% |, `5 d3 A1 q9 J( X mxArray *plhs[],
+ R+ s( {2 i! g! Q1 C int nrhs,3 L# q# E' i% s( E
const mxArray *prhs[]) {
?( x' T3 p. \* Z1 X, U8 Z% t1 ] double *a;
& N; s1 F3 q4 h0 R# j1 n C+ T double b, c;6 }9 Q. |/ k9 w S9 ]
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);& W5 M- O; K2 R5 }! j
a = mxGetPr(plhs[0]);
) W% F6 Z$ \; B; `% x b = *(mxGetPr(prhs[0]));4 h# F: d, S: ^
c = *(mxGetPr(prhs[1]));
5 r- }1 |2 o6 @/ }4 q9 B *a = add(b, c);
/ y7 e5 d9 v1 Z2 i% ^' e}
: X( M* z/ M+ i* F$ P0 Y# ZmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
9 A) M. b5 n8 D D1 {$ Q4 E>> output = add(1.1, 2.2);8 ]; E9 q/ Q+ F$ f" Z
在未涉及具体的计算时,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便是已计算好的结果了。# K' z" }& | {1 U5 l, C
上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。( P/ }; k+ s+ f1 a8 a+ S
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保2 K" W2 f) y# S3 ?( S8 |
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
9 `( S8 d- S2 F2 ?: o" O从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。+ x0 \& R% m- U. b
& ?' a4 f# e D+ B
*********************************************************************************************************************************************
' N/ r1 {. ~9 {
2 N+ m8 t1 d& Z/ A, F% E4 `4 F% Smex 的目的,
s) T& R& \+ T4 k( d+ q( P5 D; @7 o# n1 a+ |" w
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:
+ D' x) v+ u: R
" S/ r: X! W& s7 B6 E& }1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
6 t3 U0 q* b4 R
' g% E' Y' v0 h `/ Q# X) u9 t C2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
9 d Y* [& p. J+ G" `6 }5 B8 ]# u D8 k5 r) C) ~: u8 f' L
3、据称可以弥补Matlab硬件设备接口的薄弱环节.
, L. Q; G( A }5 b
/ U+ K. C% |$ H& d5 M) ~7 T2 U今天写了第一个使用MEX.
& u. Q* @ g( G* Y+ F7 r n M; R) B) { p9 J+ W
一个简单的对Matlab普通数值矩阵的操作.
3 C) x J) o0 l# r U% W5 s" x. ~0 ]$ F- W* f" g
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以" G8 H. u* j: I2 H3 f) e3 ]" t
; a M5 j. q o
一律用int代替.5 }4 H/ ]/ ^ q2 ^4 G' Z" v
( f7 F( w; r* f& L7 R6 }( M* G#include "mex.h": N* k+ D" K1 v& Z. v5 _5 F
#include <iostream>
0 K6 t5 J7 A# ]3 |" N5 n* v) u; X, t! U$ H% t4 T2 V
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
1 z4 j9 i0 ?; ?{7 d% L$ N' q# f/ r2 h# S0 O% `/ D+ t
4 C% U* c' {- d) r! {$ n# p \int i,j,k;, i4 S3 D% s8 g/ q; `" N; M' a
int index;5 E% S m& b4 {9 F
double* pr=NULL;
/ r3 O" g: b- M8 D: z" |double* pi=NULL;2 H; T* y b8 X5 M1 ?
int M,N;4 d# B, H% ~8 e5 [0 q5 b
int ndim;! ^; k5 k" f' }6 y/ W
int dims[2];4 D* S* ^- W0 I
for (i=0;i<nrhs;i++)' K+ K' @" e: ?( H
{) p8 n5 L1 N( N0 i$ J: y
if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2)): y9 e% P6 V" {* p
{
$ R" ?8 b% [8 [' D1 a3 t! \0 ^5 o: x pr=mxGetPr(prhs);
% I' Q6 t: a0 ]! ]& K: y& T pi=mxGetPi(prhs);
! x( Z5 {( t& g8 b M=mxGetM(prhs);7 I; B, h* C4 q( @. X% ^ O
N=mxGetN(prhs);4 m2 ?1 y+ g& W
ndim=mxGetNumberOfDimensions(prhs);
8 u2 @+ F& G) [6 O
$ X! Q( B0 V# L7 u7 J) [! _7 | mexPrintf("变量%d:\n",i);
. ~8 T7 u9 @- _( J for (j=0;j<M;j++)* x# _# k8 \' t- w' s
{
; E. k$ v& ~1 P. T1 v A$ {) | dims[0]=j;/ ^# z I. \- ^9 X% N
for (k=0;k<N;k++)6 q- A/ ]( ?! k# b3 G
{
* W5 i+ |1 S) j* G dims[1]=k;4 X" P5 _4 P- p; ~0 h9 a
index=mxCalcSingleSubscript(prhs,ndim,dims);6 L7 W+ j* k$ {+ ~
if (pi==NULL)' V; j4 y' s7 x# z0 S L) K' A, O
{
5 D4 [" g9 f/ z& W3 z# ^: a mexPrintf("%6.2f",pr[index]);. v4 x# ^- g5 G$ B) l
}7 D! a' A' y7 t; S
else{
1 n' c/ d% g* B2 e- R8 x mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
6 h v6 M% ~6 M1 r# X }
( e! k1 i/ l- m' u }
7 b$ U# Y6 J$ F mexPrintf("\n");
1 d; K! ~! ?" u; S0 j& N& _! s: N" r/ e* e: b1 W% [, f9 F
}
, o& b; |8 l2 y2 o- B' X& z, u $ D8 G! T; X1 S7 K. u) Q
}
: r) x# F3 S; a# v9 M else{
$ J2 w+ A/ u9 f7 L g( q% F: W mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
9 w& J& g z! |, M% r+ i}# w6 \3 }% a U( t
( i5 x0 j s2 u+ R3 B& Y; A* ]
! ]4 {, k! v4 P, ?}
* m# A2 Q+ C9 H2 z+ i2 Q
# s/ v+ g: p" H6 @1 ]! [( U- }9 t}( S ]# @: m. z6 g8 Y9 I
2 Z* p! c8 M y( P
Result:1 H2 k: `$ m6 L9 M" R/ U) j1 U3 {) d
/ q8 c, k' d u/ Z
>>mex test.cpp
( Y7 M& A! _7 @ |>> test(a,b,c)3 b' C; Z/ x; d
变量0:
0 v2 q( L' Q0 a6 \0.35 0.62 0.836 i9 t0 C# y4 a: X
0.20 0.47 0.59) _: `6 s0 G" a) N) V
0.25 0.35 0.55
3 w! L. k: F9 D' I* l变量1:
0 U# z- _. N" |- s+ q$ |0.92 0.38 0.53 0.57
. _, J. e: c8 z+ N0.29 0.57 0.78 0.47, d" w0 D1 Q6 S {. p
0.76 0.08 0.93 0.01
6 p# L+ E1 c* e) N$ c: W* e; t g, P) }0.75 0.05 0.13 0.34
: h, M9 J# @5 p5 U0 P* @7 b变量2:
& O$ v, R8 s2 q" A; v0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
3 Z* i4 H( m f' S5 E' v3 J0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j) a6 a4 j4 ?1 J
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
. Q" ^% Z9 a' W; \- s# b; v7 G; p9 l0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j. j3 C0 a! ?5 s2 H" e, R3 w
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j: I9 ` W! D5 i; [4 z
>> help test
7 \' t- P: G8 K" r3 O本程序用于调试mx______函数.2 L7 W8 O/ \: d) \; W
# O5 p: ~. h' J5 g9 o: Q% S3 ?! z- P, `. d8 }2 A& f5 C% d4 |
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html
8 u" k' M2 e `( k" {# i8 Y/ G" T3 E: c9 r/ U
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|