- 在线时间
- 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年数学建模国赛备 |
! }) H2 X- n, \2 E7 NMatlab调用c程序
& J2 V& X- d9 \+ j- M( X文章来源:不详 作者:佚名
; J8 x; \% y& D0 T% g4 m
4 a' U& u4 L9 g" e--------------------------------------------------------------------------------
\" Z: y3 q6 h* w/ n3 \. ]
% c7 R% n/ E: T3 h6 `1 O# M该文章讲述了Matlab调用c程序.
4 w, A: }# y# D6 M$ R 3 v5 Y/ A8 s+ t/ f
方法:* `& s: m8 ?: ^* {
第一步:要先在matlab中安装c程序编译器,步骤如下:9 I5 s: {0 }3 I# w2 W; I
键入命令:mex -setup;
5 s5 u- N+ {" p9 R选择c/c++编译器;. h7 R+ ]- V- X% J9 U$ d% E
选择c/c++编译器版本;4 |8 @/ b& y* i% u0 s6 ~3 q
确认。. V, g+ y4 A: Y* @7 h# R
第二步:键入:mex *.c
, l2 Z- Q7 A# t4 R- z/ g- \2 o3 x9 c+ W% u% _; J$ K
*********************************************************************************************************************************************
6 @- H3 k1 O& ]- @4 ?7 C9 ?5 E, P
; Z! V, [3 R J3 D2 p实例介绍:【转】
0 B C$ I. P% Q* Q" _. T4 k# D/ T$ [( p8 c9 @# O7 U
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
! a+ w9 w3 T: Idouble add(double x, double y) {
5 b4 W& Y/ Q. Z6 u+ I% v return x + y;
! b; Y1 l& r) d! t. c# I; s}$ p9 J; {. ~% E+ }: D/ e
现在我想要在Matlab中使用它,比如输入:
+ V7 f, E+ h2 e0 u" q5 |>> a = add(1.1, 2.2)
/ f2 Y9 w: K9 F. W7 K3.3000
5 f- B U3 J3 ~要得出以上的结果,那应该怎样做呢?
; g2 y: r0 e1 b: Z4 w6 u解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。. E- V! G2 A' X6 @2 l0 b8 \- w* u3 |
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。8 ^6 q' K! S' y9 M
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。; I4 w8 z, [4 }; m" f# v/ M& X
比如该C文件已写好,名为add.c。那么在Matlab中,输入:
% @( k- f! k9 i>> mex add.c) p! v! O, x' H+ ^0 K$ S7 f2 u1 v
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。0 u1 e: ^0 l1 ~$ I6 c
我们现在来说mexFunction怎样写。
; S* F! Z: q L2 M0 h9 e# ]mexFunction的定义为:! j/ A- w' ?( v7 V
void mexFunction(
. M% M5 |# {* h% T* h+ X( Z int nlhs,4 h$ x0 D, f; g2 C
mxArray *plhs[],
2 c- Q: h8 r9 o int nrhs,
1 u( ]: Z' M; P* F5 P% w: _/ Y const mxArray *prhs[]) {
# _7 ~, Q) [2 b/ ]. E& Q
/ d0 B6 {; o7 r s% U! o}+ u# J& x5 {( k' X# I; D% v% H
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
* Y- B; x0 b4 T>> b = 1.1; c = 2.2;- _. a/ |5 }7 Z) a9 m" u( n4 \
>> a = add(b, c)
6 l9 w: p, C n; [mexFunction四个参数的意思为:
3 M3 S1 ^; x0 }, Y5 Q+ V( Tnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
$ R7 R3 Q& C" V7 p: Z) ^& Tnrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
: T# m& B' O6 L- `' G9 ?7 k" Xplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。, L: O s- V E5 q
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。7 j- N9 R2 r. p- h6 s
因为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类型的指针数组。
, U8 S5 N0 x/ l0 |完整的add.c如下:# M! \. f' S+ u
// add.c6 [8 _) Y8 B+ j
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数: x, [# j1 U7 q
double add(double x, double y) {* }' q5 Q3 Z: J7 j, a
return x + y;# J& d8 Y$ ?7 ^6 I. L
} // MEX文件接口函数& v& [4 {: r& u Z1 N2 H
void mexFunction(
* B3 s) E& `- S1 e! } int nlhs,) s1 d% [+ }- s8 V0 ~- J
mxArray *plhs[],+ F* n7 h L5 Q. Y# s, h0 X# y2 B
int nrhs,% W" y6 a: h4 Y, Y8 ]4 \% J7 s2 o8 ~
const mxArray *prhs[]) {
2 y! n8 k) }# L0 ] double *a;
* \3 P9 ^% Y9 l' {7 } }) O double b, c;
/ B9 v6 T" J8 @ plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
9 t' O# D/ U w7 F a = mxGetPr(plhs[0]);8 s8 _* p* X; V7 V e+ ~2 u" D
b = *(mxGetPr(prhs[0]));4 a& ^+ w3 K0 z3 u5 }/ k0 ]; L
c = *(mxGetPr(prhs[1]));
) N- u2 {( p4 p5 M4 M$ G/ p: @ *a = add(b, c);, g! r- a8 N3 B3 A( t, |
} 4 D. v6 v8 g7 X7 k
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
) B6 f1 {" u5 ~" H>> output = add(1.1, 2.2);: S# b- x" ~9 o* l/ j1 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便是已计算好的结果了。
5 X+ F# A6 ~' q: ?上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。# Z6 q: f: m! h U
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保0 D8 w* ]& t7 K# m$ E" o
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。+ m6 r+ V) ~4 ^9 e
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。 M) z3 P% E- a( c* O N
) }2 l; d/ | X2 ~* d7 O6 A*********************************************************************************************************************************************
& n' [* O- ^ m" m3 n8 v3 z$ R! I' l1 ]; i. q8 ~
mex 的目的,9 K% p& w' t6 @
' |* h1 [% N5 ?2 _8 t通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:3 _% I% z1 d1 ?5 f
6 C X: f2 I' Y; `& t* Y3 u* }- p, i9 @
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
H9 R6 O& T1 ?0 @$ B( { b) x( Q4 R `; g6 h; L
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
( ^) C- |4 @; z6 g3 M$ O/ u% D+ c w R( h% E% Q$ `5 t
3、据称可以弥补Matlab硬件设备接口的薄弱环节., l6 @5 a! s0 h8 i7 E3 P4 I' h, R
$ Z/ }; d S4 Z: |% a今天写了第一个使用MEX.5 x8 J3 x1 w1 g1 R' Q
. ^( X- |3 [8 t" {6 b一个简单的对Matlab普通数值矩阵的操作.
9 d m2 _0 F: |1 W
/ E6 V& P4 N- p% A$ }其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以; D8 ^6 q n# U% O1 c5 r
+ U8 u' l4 R: A. A% c* @, @9 G+ F一律用int代替./ k# A3 R9 b D4 G0 v: {7 G. p0 @
* [! \! E9 w2 E- s8 C; V1 B4 o#include "mex.h"
+ J( k# N$ {' l#include <iostream>: e8 p6 g% X8 M/ j
) k: c* g7 o8 |2 x3 v
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
/ b* ? |9 v2 \! k; k$ q{! K1 C7 k! |2 D# f8 Y
+ }8 u4 _. K7 C& i) u+ }
int i,j,k;# R# U7 V ]+ P
int index;
! u0 I. q3 d2 M& j, z* t' M1 q* |double* pr=NULL;1 d; j$ x& l% ]7 Q# {
double* pi=NULL;
% R2 W+ k6 `" T' D6 L: hint M,N;# D- v! ` f$ d% z4 o7 @
int ndim;5 ^% l" s( `9 H% \
int dims[2];/ s9 y" R2 J$ Y- y8 I& X
for (i=0;i<nrhs;i++)
+ e6 N1 C |) x9 p0 D) t5 S{7 M. o/ y* m+ \" R, w
if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
/ W7 {8 D* p7 k {( I" y& u+ [1 F% s
pr=mxGetPr(prhs);, \ f( \8 h" V1 x( z
pi=mxGetPi(prhs);
/ D" h* G0 P' d5 h, C1 o& A F5 L M=mxGetM(prhs);+ T/ N/ a) A6 `/ J
N=mxGetN(prhs);
/ m' W' h0 l. W5 _+ n ndim=mxGetNumberOfDimensions(prhs);$ T& w( Q) e) s& i" G$ b1 ~
2 r3 t& G1 k# |" H, g mexPrintf("变量%d:\n",i);5 \ [* v- L7 C$ I( O
for (j=0;j<M;j++); ^- Z- N$ ~4 ^( f8 |* f
{. R7 B. j5 T+ f8 n
dims[0]=j;
- Z) Q# q2 f4 G X( N for (k=0;k<N;k++)
' G, I7 O" c* f. k7 J- A' I {3 f1 U& ]6 L% |& O, f* ^3 n
dims[1]=k;. n. M9 C( K3 _" L
index=mxCalcSingleSubscript(prhs,ndim,dims);: q8 H J. z; O4 L3 { t% ~9 ?5 ?
if (pi==NULL), V) ~& W" X3 I! P4 H) @: A0 Q
{! a& t& ?4 S! Y1 p# e/ L" b
mexPrintf("%6.2f",pr[index]);: [0 r2 ?! _$ e
}; D' [; m# X: Y
else{8 W* C" l; u/ A) E: M5 R- \
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);! L7 l8 @5 E6 b. u* U9 N. T
}
" b3 j( H. G9 Q$ w7 f1 D- c }
. {( ^+ ~1 h9 u9 n4 E mexPrintf("\n");
6 O# C$ W; \6 F8 c: l; V6 G! `; Z: s# [+ }* H
}
4 K4 q# ?5 c. C8 j4 Y0 y2 v7 ~$ d , o5 [& e/ b3 Z0 b' _
}! w) l# }& v# M _7 s/ A4 I
else{
4 X# M% Z2 `3 p2 P: F mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
+ o. ]! Q2 E, V7 k}
* h: U8 |0 T9 w: ^& X
* n. c- ^5 x# x& ^3 ?; N: x
4 x6 i6 [9 |* A% E& T: ^0 t" b0 W}
" \9 p' C2 ^- p. P& Y8 S) r, U" _1 j. u& m8 H# F# @! v. _
}9 N( W3 H9 T T0 d1 T
/ R" |5 Q/ q- w% z' v) {: hResult:
; y3 F" d* _* B3 b+ A2 T+ }3 l5 V2 M2 ?5 P
>>mex test.cpp
; L) E! F6 y4 h, h. F>> test(a,b,c)
/ i1 D5 j5 [; K; B* F! C变量0:0 |1 X$ Q! ]) z5 z* a3 e
0.35 0.62 0.83; E/ c0 }/ X# K5 c3 R$ ]
0.20 0.47 0.59
* V& x' C# c1 m* d% [0.25 0.35 0.55
" P" v6 d4 ~/ d0 V' l( p6 F变量1:
/ a# N- B/ K% t, P7 z6 O- h0.92 0.38 0.53 0.57
' j6 h5 r2 W3 V, H% L0.29 0.57 0.78 0.474 u! I' `8 o2 n* j
0.76 0.08 0.93 0.01
9 E/ m c9 F( m1 c0.75 0.05 0.13 0.345 `" \: @& T/ t; P( k
变量2:
* U# u9 c# A1 s* m6 j7 @1 D0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
+ h9 c7 W; b& G5 [* Q3 A0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j H, ]5 R& x1 Y9 R1 b$ D
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j* s/ i8 Q4 y6 o: a l. \
0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j2 U& _: a1 L; m# |9 F
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
9 M5 I( f3 M9 E9 k8 s. w; X! G6 l>> help test
1 i% t, K5 T* V: ^6 i$ z本程序用于调试mx______函数.% X9 M, c" r, v) e
- ]5 p' G2 S0 \* @+ ^, _/ s! ^, g
- `; ~+ _4 N; q本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html: z4 S8 X9 @: f/ Q6 p" M
! _; K" @! |8 n) x0 [8 [' z4 M下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|