- 在线时间
- 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年数学建模国赛备 |
6 A' q, ]3 S- u+ `+ N
Matlab调用c程序
. _+ @( A1 i! v) m9 i6 k3 Y, P5 p. }9 J2 n文章来源:不详 作者:佚名
: ]3 I" g0 m/ I2 v/ H( v, ~* I0 K$ n1 A3 X# G+ J& O7 }+ H( x
--------------------------------------------------------------------------------. P2 M+ t3 O3 p4 b' E8 Y! L- O
8 T9 i' d' h0 g
该文章讲述了Matlab调用c程序.
, ]( Q/ o8 l: Z8 }; N% h. m5 t
6 e- v% h; b' [ I方法:
2 j# U' ~5 U8 j' N9 [& V; ~第一步:要先在matlab中安装c程序编译器,步骤如下:
& w3 L ~" @! f# G键入命令:mex -setup;
1 [. M* @) p1 t: c选择c/c++编译器;. S2 b* { O" S
选择c/c++编译器版本;
. C; k. M6 m, ]3 M% r确认。: S9 K6 C4 C! v* {) L9 k
第二步:键入:mex *.c
0 l4 l# |* R7 e' A* [3 Q! T' p* e2 S- z! E, r8 c# A. v" u$ ?
*********************************************************************************************************************************************
: `9 X& N ^" Y$ v! i* r( {( l3 P& j! v$ `8 q" K
实例介绍:【转】" q# T' A9 P- ` v9 t, r
; _: q' p; M7 f' U+ X$ e如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
! a- C% |2 e$ S ?! N) E4 ?double add(double x, double y) {
. o( O5 a# A, S return x + y;% X. h3 ]" u) d9 p5 Q( L( Z
}" B) T9 W3 m5 P$ l5 a
现在我想要在Matlab中使用它,比如输入:( }0 G3 k) |# R$ {6 S6 ^
>> a = add(1.1, 2.2)1 c: [. s; t- ^8 h$ B9 ]2 w/ z
3.3000
) e2 l. W* I/ G) k% c, ]8 e; g要得出以上的结果,那应该怎样做呢?; D- i+ m5 ^6 R: u. P3 t4 Q
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
: D2 E0 `' @7 v- x" g0 {( q& L可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
) o1 V& j$ J" L6 F所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
! v! o/ y' P2 b6 O比如该C文件已写好,名为add.c。那么在Matlab中,输入:# C/ Q1 O/ a5 U5 C: }0 Z9 [
>> mex add.c! d8 F& `) y/ k8 n) H& o
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
/ e% I+ @6 Q7 I0 i x- @0 W( W我们现在来说mexFunction怎样写。
* @5 W( p9 ]; KmexFunction的定义为:
1 k" r* M" j% E& Z* ~* m/ Mvoid mexFunction(
( I- Q3 }( a: K" C' {6 C5 q. x int nlhs,8 F7 Q% f# X2 h8 `$ k' H
mxArray *plhs[], Z4 I3 o) Z* ]! f6 o* t! P# n
int nrhs,
, a) T2 t9 I* ?4 Y$ I. \' c5 v const mxArray *prhs[]) {9 A1 s/ z9 |3 c4 h6 j
- a! j$ h. l. v0 P! i0 R% k+ G. y& q}
6 Q$ ]- P0 q. z( K可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:, b& ~- C4 p5 x7 k! F
>> b = 1.1; c = 2.2;/ r6 r3 a; ~2 d, C2 H: w
>> a = add(b, c)" T3 P8 `- V: [2 K1 O
mexFunction四个参数的意思为:
- S+ [3 Q( a/ J! |) P1 v8 mnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。8 w' W/ C3 ~- v; A
nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
$ W* Q( f1 ~- W0 f6 |plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。4 d7 ^3 [+ A$ g7 z. v! K
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
) b9 L. }/ R9 \* a! T2 T8 | u8 A2 d因为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类型的指针数组。3 B7 R4 r" `6 ~! ^2 b0 s
完整的add.c如下:8 `. J1 }' O, j: n3 N0 D- B
// add.c% i8 b; d! f, b- _
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数/ J) Y8 n; l" k- V
double add(double x, double y) {: z% t# i. |! Y3 Q5 U) p5 s/ q
return x + y;
- X: d7 z' n" R J% l, |} // MEX文件接口函数
" ]9 S0 H1 [+ Avoid mexFunction(4 u; C+ d! M8 [
int nlhs,) P! y( Y5 j0 ~. I# ^
mxArray *plhs[]," d! p2 t, }% L; a6 p# ~6 Z- i+ u
int nrhs,6 G" @2 w& d6 L1 Z2 Y9 c& M; p
const mxArray *prhs[]) {* c F- t/ U" S& p+ g i' o# p
double *a;
- f7 z! k; b: r8 M! A2 ]% r double b, c;
/ @. v: g- L9 F# h) V ~, M plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);) A. Y u0 F7 u( A; T7 Y
a = mxGetPr(plhs[0]);
' M, i5 A1 ^/ ]% `5 I8 j7 O b = *(mxGetPr(prhs[0]));
8 P/ B+ H5 j! U& u. ` c = *(mxGetPr(prhs[1]));$ k6 B' m3 s; H# W. I
*a = add(b, c); s! _! u% v/ b( z7 \$ W( b; a
} 3 e, E1 `% A; N) r
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
2 S( o1 s( k+ |& X' W' d5 E>> output = add(1.1, 2.2);; O$ v$ N5 @; d
在未涉及具体的计算时,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便是已计算好的结果了。
/ _% A5 n: l. k R( i _上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
& o- K9 r0 e/ K% T: n实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
- J }4 B$ z9 k$ P输入正确。如在add函数的例子中,用户输入char array便是一种错误了。2 C: b2 H& A4 K; {. F3 W% W4 k
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
$ j7 x# e4 O! z" W. g/ k$ m
% e1 @# K* l( A# e% H* S1 B*********************************************************************************************************************************************& @- T, Y5 B; `; {5 L4 w
$ h9 O* |# j3 q4 R0 P, `) Amex 的目的,
# G" s: }" B' N" J4 R" Q1 @1 R) Q! k4 N- T* |: K
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:. o: G. N( E0 c# E+ I# H$ C
% @: Y- P3 w4 {8 ?1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
# S% x% T8 _: u4 o6 T0 ~$ }5 z/ v* c. z/ x8 b0 G* [- ?. m
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
4 _* R( J6 r) j; Q9 k7 A* q7 ?
7 G; p5 Y3 B) [: E" ^* J6 u- v) L3、据称可以弥补Matlab硬件设备接口的薄弱环节.
4 n# N; h( } H" o' [3 C
# S( \& f* s4 p6 B+ k今天写了第一个使用MEX.
4 k0 y* G$ W) Y C
4 E; Z3 r+ {0 B+ }4 C一个简单的对Matlab普通数值矩阵的操作.1 y4 u- c& Y i% {
9 K# E; j9 z5 [, g+ K
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
* D+ g1 s; \# i
% X/ V' m3 s1 S/ S; L; Q5 r一律用int代替.
8 R9 {$ Q7 d; W. w- s4 u( j
5 K3 o1 D' o* i0 a#include "mex.h"
( [4 r* i1 ^/ }2 @/ d#include <iostream>
& H9 G2 C/ i: ^( n8 c. N4 E0 l9 S0 n: [9 S) a
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])/ e! g: B0 s/ G$ F
{
+ O* L( `; R& ^ d7 C7 ^5 _( g/ ^; ]6 Y
int i,j,k;% j% M2 n: P, x( C0 ~' M" h
int index; k! M+ g: O) _0 n
double* pr=NULL;; [/ v& W; ]3 O) z
double* pi=NULL;' ^/ A+ w. t2 Y: h. b
int M,N;
8 {8 K1 w/ G# h9 ]* U0 J% e8 |7 Xint ndim; z# u+ t" R) @' ]% Q6 w
int dims[2];
0 D5 a, R; X( d& V% Z! Rfor (i=0;i<nrhs;i++)
) f! ?5 [ p: K; |: r{
" X1 A2 A; f$ U/ k* |, U/ X if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
9 H% H& o0 n- E) e' `2 u7 q {
6 f9 q, [8 l b: j* r7 { pr=mxGetPr(prhs);
9 W% C' T6 ]; C pi=mxGetPi(prhs);, p9 H: L4 W3 v& r, h+ @% ^6 [$ M
M=mxGetM(prhs);
2 }# q1 T: g% q w+ c, S N=mxGetN(prhs); Y7 ~& O6 W5 k0 o
ndim=mxGetNumberOfDimensions(prhs);
3 o( g: t% k' F8 u
$ T U9 P8 C9 C: ]' x1 Q7 ]" S" W mexPrintf("变量%d:\n",i);7 i5 U; Z7 o- r1 |
for (j=0;j<M;j++)
6 R, m, G) H' I6 v) q7 R7 N3 [* Y$ N. x {- ?+ e1 b8 U# S/ J
dims[0]=j;
0 @( E3 ^) r2 e, T& i4 N for (k=0;k<N;k++)
1 W G9 u ?+ A$ f {9 P* W7 u) M' o
dims[1]=k;4 M' l+ y( K4 L- q% \2 [# S
index=mxCalcSingleSubscript(prhs,ndim,dims);
0 D+ w8 V1 n$ y/ ]$ M4 m if (pi==NULL)& r) E, P/ v# \$ T, Q! }
{
' N9 T' }3 I% K mexPrintf("%6.2f",pr[index]);! t0 j! A2 `+ F, M
} |5 C* g- ^2 @5 D; o4 c
else{/ Q+ A9 y! r& _
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
$ {$ l- W; t8 W1 H% E }! R. S5 o* u' u( B
}2 X1 K! w7 I5 G7 T- `
mexPrintf("\n");9 g* e# Y+ A; m ?, ^6 h0 K+ f
( g- V& }1 y0 I" ^3 a5 @: T
}, I- g, J2 A+ M, I1 L
- I3 B! U- u' a$ k: D$ M }0 X1 _# z& c( s' ~: \6 x( o
else{
6 K; D5 j5 o+ z* W% i mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);& k5 J. [( }0 `: U2 `
}; W# q9 ^/ T! P& n+ Z
5 M4 s+ {$ \$ U7 S7 y, q
! p. A5 ^- P4 F9 W: {& i
}4 k$ Z' J' |! F$ E" O8 k
5 t% z# t, r3 t& U. U2 `
}
" f4 B2 E* T2 `* K! A7 R8 w# i n/ g( [1 b: y" c9 y
Result:
5 ?7 A! u- _% g% u; T$ @+ k9 Y# n( Z. K7 l- i7 t9 ^
>>mex test.cpp
, z B3 C& K2 a; }( d>> test(a,b,c)4 U( \# s: ~- x- R9 s9 v$ a
变量0:, H6 P7 ~ q& M5 _* q
0.35 0.62 0.83$ ]% L- I+ t; l' c0 \& d9 a! H
0.20 0.47 0.59
7 g5 R) d* e! I$ h! V7 y0.25 0.35 0.55' u/ h- |5 D3 @! m" `
变量1:
! C& l! W/ K$ c& h: Y0.92 0.38 0.53 0.57% s# A+ f$ q& V( t
0.29 0.57 0.78 0.47
( _' m) M. a/ _4 o* a4 s0.76 0.08 0.93 0.01
- ?% ^1 E* X, `! X4 z$ i: \0.75 0.05 0.13 0.34) X; z1 ?! _, Q) D$ F1 p
变量2:, ^# `& H. D& ]# @* o) U& Z
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j3 s# x, I& n. k' u, o3 N: k
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j: ^; }7 q8 L/ n+ a4 q" G
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
; ^ E* F; s- l" t& k6 {8 \1 r1 |3 x+ k0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j& S2 Y6 g: P$ K N! V5 `
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
- a" X1 y& [# E, w% V; m, c>> help test! `* M2 J$ W% X( K) Y
本程序用于调试mx______函数." N9 d4 h8 b. _. A. J
- g' x' N J z& R" d# K) h" L8 \8 ^) t& a* n6 X: N3 M
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html1 \8 h) e6 a8 X$ |) g
& ^4 f9 U3 _* [, j+ `2 y$ j
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|