- 在线时间
- 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年数学建模国赛备 |
) o( f5 k/ y9 d$ H
Matlab调用c程序3 |! N, f) K# T' Z$ S2 i$ P! q6 p
文章来源:不详 作者:佚名 3 W! R4 p9 L% f+ d
7 ~* z! {3 @0 _--------------------------------------------------------------------------------1 i5 l1 `& ~3 l- C9 z4 p
% ?9 d; p6 K, v4 U, j q该文章讲述了Matlab调用c程序. l5 c- W" H: |, p
( Z: D5 C) X6 M% y方法:6 U) J+ d/ [5 D% ~
第一步:要先在matlab中安装c程序编译器,步骤如下:
. M7 I- `2 J& t8 }5 |8 W( `0 B键入命令:mex -setup;& @7 ~* D. i5 g/ ~
选择c/c++编译器;& B1 i j# Z/ p z& z6 K4 [
选择c/c++编译器版本; w- t3 z7 N# Q' R; \% m8 w) q: y
确认。
8 ~. _9 N, N6 W4 h b$ f第二步:键入:mex *.c
* w7 Q- F3 a5 L0 X# D7 o! K0 \. V
*********************************************************************************************************************************************9 g8 p/ p2 u" w
& C2 g& A/ w0 `8 D
实例介绍:【转】! @; {, E/ ^6 Y
+ ?0 U$ h" n+ G如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:" X* {3 Q$ W0 s2 H
double add(double x, double y) {* Y' @; z2 V' \. C5 w+ L; T$ i
return x + y;
: t) j( G/ z, `/ n6 W8 j7 |}
, [% C3 c3 |6 R+ |* n5 _现在我想要在Matlab中使用它,比如输入:
' U) h8 N9 f( B+ Y6 {2 k8 M5 t>> a = add(1.1, 2.2)
( M- Q4 w- i. P# L3.3000
; y; {" z: f; y0 D, }要得出以上的结果,那应该怎样做呢?/ g. v' V. X J( ~
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。! ~% i/ ^7 Q+ x+ H4 A9 J+ n) Z
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。9 R* B3 j2 w& }- I! }; B2 t
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。7 Z/ ^' C+ ^; ~1 x+ V% f) A) e4 D9 _
比如该C文件已写好,名为add.c。那么在Matlab中,输入:
% ]8 e, Q! p0 k>> mex add.c
$ i. G5 b2 A9 ^1 G就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。$ ~0 b- `$ q) {% N) X% v' s
我们现在来说mexFunction怎样写。) G. I: n5 f' [4 p" Y. i
mexFunction的定义为:
2 S. t+ t2 s/ h% K. Xvoid mexFunction(
9 E% n, G. \7 Y$ n5 ]; T! ^, c& ^7 K$ Z int nlhs,: E! f1 R6 h1 Y7 k0 {
mxArray *plhs[],) U, E' \9 R B) d2 X9 f( [8 X
int nrhs,
8 k/ _5 Q6 g0 ~' A+ U: P const mxArray *prhs[]) {
6 H n) D4 j; P: e ]
) B" B! e: _3 X4 n}% c/ J5 H3 i' ^( _6 Y' S2 B; ?
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
, Q& x: ^5 P' d Z) g>> b = 1.1; c = 2.2;! E& y& W4 M* y& n r0 _
>> a = add(b, c); w7 b! p0 c1 a
mexFunction四个参数的意思为:
+ ]9 N4 D) P# j7 Z# Cnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
0 s2 L0 z- c- {$ Pnrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。' |& ^7 [. T p; V9 [4 V
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。3 s7 M: N$ ]; Y! ^) P
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
: p c4 V) M3 l6 ]- l% l8 V5 x因为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类型的指针数组。
$ y! E8 b, A0 S# ]) O1 ?完整的add.c如下:0 \9 c. G: |8 _/ l9 X8 ^ T
// add.c
/ [* C. G$ e9 @2 J( c" T#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
0 a" i% X! x( b2 L2 Cdouble add(double x, double y) {
# B$ C& w- j& [- G* S, W3 j return x + y;& @0 h+ ~9 N B- q
} // MEX文件接口函数" R5 _% Z+ {9 M: Q% ]) Q8 D
void mexFunction(
. g# R# ?! B/ ^9 r0 i- u int nlhs,
+ s% S% `9 g2 E3 S4 T mxArray *plhs[],$ X2 l6 M, V* V* C& \- f* k7 _: {
int nrhs,$ |$ @; x1 p/ s; c, ]
const mxArray *prhs[]) {
, C |6 }% K* @ j X) C8 c double *a;
: K& l2 J& y7 T3 j0 n double b, c;
8 H3 o3 D% }8 k3 Q* [$ M+ x, U. ? plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);. E4 {& h7 j# b2 H
a = mxGetPr(plhs[0]);
' T, {0 D& }1 X. i& `. t0 n l) S b = *(mxGetPr(prhs[0]));
: k' n% k0 U A m7 u' I' f c = *(mxGetPr(prhs[1]));6 |1 j( \7 R. l B+ |( L
*a = add(b, c);
$ ^% l7 v# h2 f5 Y- h8 V}
$ ?+ R" j [2 Y1 s7 H7 C" QmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:: d0 ?2 Q# E+ S2 J5 ~* o1 b
>> output = add(1.1, 2.2);" @- ^* ^$ G. V U, G" K5 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便是已计算好的结果了。5 c6 r6 {; ]: Q* D" T) U
上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
3 w q& q6 P6 c! U. J实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保# b J$ ~2 Z9 ?: P' Q
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。, h5 w# w: ]' L" p2 b6 H/ L; H
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。6 V1 R2 j0 ]/ a; J, Z% Z. g
; ]" l9 Y8 @0 Z5 x. q) g
*********************************************************************************************************************************************
0 d+ h: O7 P3 j7 L) |& e$ f# X5 U4 e ~' Y g( n4 G
mex 的目的,7 g( V# e, k! ]% ^. Q' M4 A# V
& N( U6 J1 v/ h/ K+ d* ?2 s' g0 V
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:- T, e, ?; C' ~
^! g+ w' }- t6 n( e, b* Z1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
$ v W* R0 ~# p% w: H v, G& j8 Z5 E/ }# ]
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.( K) O9 D* u& J8 @8 I
% \: @8 p& }0 Y$ K
3、据称可以弥补Matlab硬件设备接口的薄弱环节.
( ]5 d: P9 p/ K& L& [! R: e5 y+ L
今天写了第一个使用MEX.
; H3 V8 F Y# {, [- r. Y( e2 x" E3 O
- h0 K4 |* K% k9 s一个简单的对Matlab普通数值矩阵的操作.8 N- D, h" Q8 F. f' f x2 t
: s7 J) c5 H* z7 ~
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
/ N" Q; Z( M z+ M% E( v0 {* f
. P) ~2 e1 A; P- p$ P* q一律用int代替.
- k7 z2 d- g _6 q; ~! R: K1 ~* @. U5 C# m; j m' M6 v( S
#include "mex.h"
1 }/ W$ r6 H; F3 h. Q#include <iostream>2 J1 L* H# ]: @ f6 c
. q( t7 U8 | _, N, b! x" Jvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])+ M, e+ [7 O" V5 R1 _
{
7 ~# k7 c9 k7 x3 f1 m7 {# W3 W4 ]! G1 z6 s( M' s0 k9 \" J% V1 o
int i,j,k;1 v( y6 J/ j8 a3 B9 a9 {+ P4 o
int index; h3 E* G$ I. f' v( @
double* pr=NULL;# m+ h; b1 l% k
double* pi=NULL;. I& u$ p1 {& U$ g: F6 h' `7 g
int M,N;6 s4 h" x7 ?( W7 K5 ]! T. D$ _
int ndim;3 X9 l* p8 K$ W; p: m
int dims[2]; H3 i# n% K' f
for (i=0;i<nrhs;i++)
9 R# X. d2 j+ p{
. l: v* M" `6 y. _' F! q4 N( a if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
- ]$ V! V1 W5 O9 k3 {( m/ ?4 w$ | {
+ x9 D( `6 l# G }7 N pr=mxGetPr(prhs);$ c5 s- M5 e" n6 G: o0 O
pi=mxGetPi(prhs);
0 k- ^1 H5 ^% p% r M=mxGetM(prhs);: S: ?# o" w4 s- [5 o
N=mxGetN(prhs);4 {# \) B, ?, O7 q7 C" l# Y
ndim=mxGetNumberOfDimensions(prhs);
* U' Z+ v1 M/ j3 T" ]. v/ {1 ~3 ~7 {1 r, c- `, X* T
mexPrintf("变量%d:\n",i);
4 { F3 m# g/ G8 ]. B, c$ G1 b for (j=0;j<M;j++)$ u" `' i1 H8 M0 K0 Y4 u* Q
{5 V3 o$ f- h# u) k- U6 d9 \. o
dims[0]=j;
2 N) I6 d# r9 E/ C6 W0 } for (k=0;k<N;k++)/ J# E8 d; b- T! m% J
{
9 Y! ~7 z$ |' h& }: i dims[1]=k;6 Q3 F) a4 J5 o8 k) u
index=mxCalcSingleSubscript(prhs,ndim,dims);0 l5 K7 P$ `/ b- M! j7 V* t
if (pi==NULL)
^ c. e# z$ u- t/ H( Q; v; U {
/ d' r* D: m5 _0 H' }2 |) n mexPrintf("%6.2f",pr[index]);. ?+ d1 w/ }. M7 d3 h
}+ d- c0 u( x. g& E B! j; h
else{+ Y0 H* t j( [/ o4 f
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
, r9 Z6 E& ^% B5 x- }& G: k ~ }
$ l t7 o+ N0 v9 t, N. f }
0 @. ]2 ^" V; f+ N' g mexPrintf("\n");, M- w- r9 D }9 p4 o' y
* j, i: U; R! Q4 z( |3 z7 L: ~ }
: K0 W1 k9 O" m, H
1 Q: M$ b2 ~/ P/ x b- ? }
5 F6 ^6 Z* {. Y1 w/ q else{
3 u7 k( r" W A- Z- Z; W9 }( l mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
$ c: M5 B; r* q3 [' r% o; G8 V}7 M$ W: O! {8 M8 D. N
0 d# H* ?4 Y$ Y* u% c: O/ q& H* z, T
1 D# I+ X3 D8 A! j" z: e4 K" o: @
}; x$ g8 M6 q' l5 }
# U' E! c( F$ o! R& x6 E
}+ g! D( T8 S' d# u* C
@% i6 M4 e0 y, a' _' MResult:
+ u' `" E( R- p( _+ O8 j: z# W" ]$ ~6 Q# G! n
>>mex test.cpp' Q0 s# v2 a& b. g
>> test(a,b,c)
0 S0 ]6 @0 U. M* D变量0:( k; F- b# s/ f) Y2 x6 H/ h2 r
0.35 0.62 0.83
9 V9 U% r+ z3 X( ^0.20 0.47 0.59
1 J- [) [5 u& A" _: f0.25 0.35 0.550 L# B1 o% n. W% G2 E8 b% E3 o
变量1:: H( g3 \1 [ `9 o1 e% b4 d- V
0.92 0.38 0.53 0.57
6 \ T* c$ ?* E( Z) M4 @5 o0.29 0.57 0.78 0.47. _! C3 Y, S% }9 h5 r% y
0.76 0.08 0.93 0.01, Y" l' H8 I8 Q* [' H) }1 O, O
0.75 0.05 0.13 0.340 m/ [' ~, \' n. @. c1 P4 u; ]2 L4 d
变量2:
# Q% B6 A4 G; c0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j' u4 q3 k/ Z% a) W, {% K ^1 h
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j0 s. o1 v7 Z- \ Q; N, W$ W
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
2 t" J" J. i7 w' C3 L" M0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j5 m1 v! F; ?2 h: _ Q1 v
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j% _/ Y P9 v9 [; e8 Y+ j
>> help test
2 A! T* Q8 W! e0 G2 `) G本程序用于调试mx______函数.; K. x$ V3 U9 h* J
- W1 q& Y# ], d) F* I0 n9 m
; I2 h/ {/ [2 y3 J) \ _% }本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html2 ?2 K2 w y" n6 D
. g/ D2 p7 m7 ^0 h8 u下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|