- 在线时间
- 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年数学建模国赛备 |
' w0 K R; _ FMatlab调用c程序
- i t% \' c) `- f文章来源:不详 作者:佚名 8 K. ^$ V8 B6 j! n ?
6 ~- I; ^0 g7 O8 D h$ ?8 j--------------------------------------------------------------------------------
! ?% W) ?3 {/ J* N. Q& Z* N
9 ]; ?7 {6 g) s2 d z该文章讲述了Matlab调用c程序.. s2 b/ G4 p7 Z X$ l
9 j# n. d) e1 e; F
方法:) Z1 Z8 w' @/ R" T3 h9 \) t
第一步:要先在matlab中安装c程序编译器,步骤如下:
7 x8 S9 }5 E* P& k7 w( f. L键入命令:mex -setup;- I4 n5 r0 w8 q0 E
选择c/c++编译器;: x+ \* p; J1 }( j# n) Z) y
选择c/c++编译器版本;4 ~. l$ q; v, e
确认。9 i D# w/ M6 }
第二步:键入:mex *.c3 ?+ y! ]# ~+ ^* v
! V# _* |" q( i; c$ C, r4 e+ N
*********************************************************************************************************************************************: q6 L. E9 J3 W. |/ K
- F# T/ s3 C) N实例介绍:【转】
$ {3 i) I1 |, j/ i" B8 W$ m2 _
7 F$ ^/ k( m( {% C, f$ z( @. L如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
9 t. A! }. m; w) gdouble add(double x, double y) {
0 @! b, R* |& l return x + y;" j. y' X( j! a8 w7 q
}
I% _. d1 ]9 }5 O: T现在我想要在Matlab中使用它,比如输入:( z/ O0 F5 u5 Y$ T8 i
>> a = add(1.1, 2.2)
6 x$ Y( }* B9 X8 B3.3000
- M5 d( V7 w! V要得出以上的结果,那应该怎样做呢?
6 B# ^+ B( n, z+ M2 p解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。" v4 P0 g) _' a0 y0 R- s
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。0 _% `: z+ e+ m; v4 |) O$ T6 N$ \
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
$ ^/ h" l4 h" C. v( V! E* Y$ f0 ~比如该C文件已写好,名为add.c。那么在Matlab中,输入:* m( U8 F& G+ @' N* V, X
>> mex add.c$ P7 X" ?1 P `9 j9 _1 Z
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
4 C( U+ a) k( c: U6 |% U! n* K我们现在来说mexFunction怎样写。
5 @- D9 |/ m4 a6 \) \% umexFunction的定义为:
5 a* |! G! U! I B5 L0 }0 `$ Bvoid mexFunction(
6 W: ^' J1 e) ]7 e int nlhs,7 \1 K8 T* Q2 [- q, E
mxArray *plhs[],5 N _" ^! c) V" \
int nrhs,
! v% T! ?, ]; l+ A const mxArray *prhs[]) {
; o* T3 {5 M2 I# l
: j, ]4 ~0 C3 U8 E5 d: P}- T6 Z* C) I. S) A: t4 h
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:$ [$ v: |% B4 v. N
>> b = 1.1; c = 2.2;' M: U0 |) y+ d2 X
>> a = add(b, c)
+ Z% Q: N. |4 a; ]mexFunction四个参数的意思为:
! d' i" d' g4 fnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
" w! ]. B/ }3 |* _nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。2 e: |8 c6 U0 _
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
4 d& |0 r; d4 w6 b7 ?) Rprhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。& g* F2 C0 H0 k: n7 N, W3 W
因为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类型的指针数组。
% d* E+ W# R% q1 r! `完整的add.c如下:3 W% o$ ?+ @& H0 K! D, q0 j5 j. K- |
// add.c
" e3 d- a" Q( T. K5 M#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数9 J/ N: \# q% F" K4 `
double add(double x, double y) {; ^2 z, C" B. u: q5 {- w" x8 X! A X
return x + y;9 ^6 \! m0 A* f/ }; [1 l4 }2 U
} // MEX文件接口函数
0 Z! l! F1 s1 {void mexFunction(
4 A! O+ X4 e) G. `% S7 u8 ~ int nlhs,
! }* n+ {/ `/ b5 K9 @ mxArray *plhs[],+ ~& E# V+ I0 N1 A
int nrhs,6 m! k+ _" C2 K
const mxArray *prhs[]) {$ z, W$ ~- H& T# a) K8 H
double *a;: N! [3 {! c* J0 a* v
double b, c;
( ?6 L7 Y6 Q6 B$ _ plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);+ [' l% \. W# o
a = mxGetPr(plhs[0]);; V. n& S, x' O6 ]9 p2 O/ t" Z1 ]
b = *(mxGetPr(prhs[0]));
. g' `& L- O- B) |" Q c = *(mxGetPr(prhs[1]));
4 [, Q. O5 }% |1 f7 x3 N/ \0 B *a = add(b, c);5 X G( P2 c: s1 J
} 2 J. f: ~# l4 B' `
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
' O/ J/ ?6 | ?' n8 n. s' ~>> output = add(1.1, 2.2);7 N) Q9 E) H3 x5 m8 S
在未涉及具体的计算时,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便是已计算好的结果了。
. I# ]4 B* j) O, U1 r6 u0 W上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
, I9 {3 W* e8 x2 E/ E. B/ ]实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保0 f# M* {0 Q! v
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。 y5 Y1 z- X7 G' s* P8 b& s" l% A# p
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。, }8 q% c$ z- @2 B" ]! A& K" A
- B( a' @# R: b& Z$ _
*********************************************************************************************************************************************; q. P( o/ Q/ ^) m5 p3 r$ n
! B+ e4 y/ Z8 h, omex 的目的,* h. W/ e' |0 m& d
, a+ A7 v" e/ Q& s6 ]' {2 i2 u9 _通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:# }0 N3 \/ @, Y+ ?+ m: V5 ?% F
2 \6 Y2 m7 C4 c) H# Q- P; b7 x3 D
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
& S: {3 N9 N7 k3 C3 @& k0 m: ~9 [. B% I5 F+ ]
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
5 t3 c2 n, M2 m$ b% I$ g" S
, l B* y5 ~5 l7 f5 l7 h3、据称可以弥补Matlab硬件设备接口的薄弱环节.
2 B2 h- X+ V, y- n! i. w1 w# ~! N5 K+ D; q+ J3 B
今天写了第一个使用MEX.
5 s [. e4 u; F. w2 s6 h; |0 `$ d8 _4 [1 Y: u- k( H# e
一个简单的对Matlab普通数值矩阵的操作.5 S! q0 }$ x/ o! D8 Q
) i& f1 [% v& N$ z" y
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以- @( o" `( |- R% j) ~( j
- H; z7 H! g( @$ y7 a) i; B一律用int代替.
: I, Q# F$ C/ A/ m3 W6 |- k: c8 r* I' E) I# ]
#include "mex.h"4 z; P: T+ l1 J8 H
#include <iostream>
) D3 ~6 S8 ?4 q/ U( T% j$ V
. `' S/ z V; p. ~& u5 M8 mvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])7 ]# ~! o8 Y, A4 b; J. _' n
{
% r/ A* B! O' n) g, X1 D5 i6 {; i4 t# A, M" ?% \9 l% C
int i,j,k;4 e+ k: j; B3 G& A$ O! R
int index; V% r+ S# r- W( E
double* pr=NULL;
V: f# J3 Z2 `1 M# Y- @double* pi=NULL;: U6 t: u1 R! C; o8 N E& O
int M,N;$ J; ^$ v2 e: A0 L7 u( y
int ndim;
8 d1 ~5 m# L/ X/ u! Xint dims[2];6 z+ [" E- Q3 H6 O
for (i=0;i<nrhs;i++)2 l9 l% C( U0 g# c9 {7 @
{
# j# O$ ?& \" ]8 t3 |- J) R' @# ^) K if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))$ Y* z$ f. _: q( n
{8 y$ H1 W4 c# v5 p* Y; Q7 O i( B
pr=mxGetPr(prhs);& A- F, z- g1 R( _) O
pi=mxGetPi(prhs);
S0 w) j5 A+ @" } b | M=mxGetM(prhs);
5 _, d' }# V: c' O( B a# F N=mxGetN(prhs);0 u; p- z. `- Z! D$ A
ndim=mxGetNumberOfDimensions(prhs);
" p4 S! O* H7 ]* K% e% |4 S& P3 p( t5 A4 n+ p/ v9 A
mexPrintf("变量%d:\n",i);& }4 b2 D5 r( t
for (j=0;j<M;j++). L* [( k, D/ }: K+ B# J
{& F0 y" @/ I3 y+ ]0 m% M3 G2 L
dims[0]=j;
. u% ]; u0 f0 j" L- H% j8 a for (k=0;k<N;k++)$ C' G* B8 U4 \5 ]) K9 w2 u! d; N! j
{- U W5 K# Z5 c1 f& t
dims[1]=k;# x) z9 i" O2 `/ g0 a2 k6 J6 Q
index=mxCalcSingleSubscript(prhs,ndim,dims);
- B# w7 t% K& [$ m if (pi==NULL)# O7 s1 O3 S. b
{
, t' ^5 C1 O1 M- D+ u5 x: ^ mexPrintf("%6.2f",pr[index]);% }* B1 _5 z' V$ I9 l, S& }$ ~
}
# X1 X* h7 x8 G2 N else{
! {" e$ M& `0 |# T- u mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
2 @6 P# E) V E7 p2 A, C }5 E# H ]3 E/ c
}
5 ~: A3 e d9 ~( G mexPrintf("\n");: F: p( t* F; P9 G4 q
$ z% j7 G; V4 ^$ a( V& E, F& b
}# W# H0 l3 Y! O/ R6 G( V
* E& o/ p' u$ Q% V! f7 K
}
" ~" l- N6 K6 b, D7 f: a else{
3 [# g) t c$ o mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
! k* |; ?: y# `/ W}4 L2 g3 T8 x5 _% i2 v
( ?" a- a) Z! {! A
8 h5 I: s1 u, `4 E}% Q1 f, _ a/ M% n. w. D' O( f
( j. i, @! U7 g# j- ]5 B1 Z+ R}7 S* T) |' R3 S$ s/ I+ t
2 c2 \& j8 w9 ?% d; PResult:
( A$ b: I8 N4 G+ Z1 r$ ^/ e7 x, s9 p" I; F
>>mex test.cpp G5 O! y6 s- D" t
>> test(a,b,c)6 k' f8 W# R k# g+ Q
变量0:2 o/ b* E! U: D# f5 U! |
0.35 0.62 0.833 s/ U \- N. s% Y, m9 p0 `6 n$ G! E
0.20 0.47 0.59
% z. ? ]1 M* F- `& S, ?( J: A0.25 0.35 0.55
& D6 V4 L. k5 ]3 m; P/ N' J+ d变量1:
0 |" D5 A% h: f/ |& S0.92 0.38 0.53 0.57
# z; J( B! {( {0.29 0.57 0.78 0.47
& R& b& |% C1 ]! D0.76 0.08 0.93 0.01
5 h" n! i5 d2 R- V3 q0.75 0.05 0.13 0.34; a0 o$ T: v3 C. j/ A" w
变量2:
; H7 g) n" u M# w- h' k, T0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j* z8 U; r% ?. H1 Z) e
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j2 B) a0 k% W! L7 D9 ^
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
, s9 _2 [- U2 p! n' e6 I; i0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
9 _7 m4 s6 `) q0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j: p9 `# s \$ ~" h' R* V
>> help test; A/ q. J/ Y$ |
本程序用于调试mx______函数." }# ~1 J5 ?- H0 ^/ B2 D
: b3 U& i* w& ^
/ e% A. ^% Y; u3 X9 j3 z7 x本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html
& i- ]( H; `, Z2 z, I! r) m1 H( [
n' D# [( {* `" O: A下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|