- 在线时间
- 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年数学建模国赛备 |
, |) a1 u6 k% r5 h/ eMatlab调用c程序
2 h5 C! o. _! V% v( h文章来源:不详 作者:佚名
9 X( V" _+ o" F5 `! b3 I! ~6 o; n3 l% l% v1 ]
--------------------------------------------------------------------------------# v2 b9 t" A' Y& w1 @
4 T# j6 |% q$ |4 Y, O该文章讲述了Matlab调用c程序.2 U5 p' @8 c- S; Q" s/ Y) O/ Z& E
9 m% i) K, P$ m% k6 C4 K
方法:
! Q4 b6 }" j5 q; f: q" k第一步:要先在matlab中安装c程序编译器,步骤如下:& a1 b# R9 G, y
键入命令:mex -setup;
, |3 k; m6 f) w选择c/c++编译器;! M5 q. Y* J! }+ Q8 I- a
选择c/c++编译器版本;' m* o* u- _* k! X Q
确认。3 Q3 [) r s# q
第二步:键入:mex *.c
, C% k2 X0 N' v5 x. I e1 W: q+ {, j& w& q/ z' P
*********************************************************************************************************************************************) [ q [; q' I9 S
0 W0 s0 X# [$ f/ u/ ]9 N实例介绍:【转】- f' d4 R/ F! F: u- M6 I' D
4 i& H$ o$ d! b! \/ w. y: f
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:* f; q' X# R, m& u9 j# y7 K+ S
double add(double x, double y) {
6 X5 Q R8 m8 z' B return x + y;
% v% A9 [% L- P7 f' @5 h/ z}
, K; g8 ]& H' F) |* q1 k现在我想要在Matlab中使用它,比如输入:
3 |3 h+ S# C, Q: c/ @>> a = add(1.1, 2.2). K; X- P4 g: w q" }) c2 f
3.3000- Q/ C2 l$ ]' k0 B
要得出以上的结果,那应该怎样做呢?
" }0 G! x/ f7 \解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。" @5 ]: o0 O5 W5 T
可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。0 s! o8 u( q) J" z" d# F
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。: ^$ i$ D1 M6 j/ s
比如该C文件已写好,名为add.c。那么在Matlab中,输入:1 B: m9 J, c! b3 K7 q0 H
>> mex add.c w8 f5 `: w6 Q. K
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
$ y ~/ [5 m5 j' b我们现在来说mexFunction怎样写。
. A5 k& N! z7 p, l2 D. d0 kmexFunction的定义为:
3 ^; ]2 Y8 ^0 N* E, b1 }8 f7 @( A( xvoid mexFunction(/ M/ s) {6 h: [$ y+ N- b7 q+ y) ?
int nlhs,- J( H9 H! \! K+ y$ V
mxArray *plhs[],1 P6 B* z5 A0 ^5 k& Z. @5 L
int nrhs,+ e2 I5 m" f5 q" u" V4 L
const mxArray *prhs[]) {
& t6 m' H. |$ K( [" O) a& u6 |1 a7 E6 Z8 E
}5 t& e$ n6 e1 J. Y( L2 {/ a2 y
可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:5 p+ H& k) C) {
>> b = 1.1; c = 2.2;* k# k- m( v! f' I( |' S7 n
>> a = add(b, c): Z" u5 r# ?. j: m5 ?7 A8 m2 V
mexFunction四个参数的意思为:& T2 Q1 n* L$ o: |: O
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
# A3 Z, B( X) o# t* ]nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
' ?: K$ e% t$ Y; w: \( g; zplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。6 I5 g' n* f a0 N1 z2 @$ n# D
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。2 O) @, R2 r4 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类型的指针数组。
6 e1 @! _. M h9 X8 B完整的add.c如下:+ ?! T$ c# @5 D: l
// add.c
# E1 T3 m6 q7 f- d/ L* ?& L#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数/ B$ U: z5 Q! ]+ d
double add(double x, double y) {$ H! a3 e% N# E: e, ~
return x + y;
8 N2 \9 k+ C$ {" y} // MEX文件接口函数" @+ w8 ^8 v$ q* {* O+ j, x
void mexFunction(
/ p0 h3 y! o& R; v int nlhs,
' Z2 ], F( `5 u( Y9 p; i mxArray *plhs[],3 K' i u7 Q4 d9 B2 b' X8 g
int nrhs,
! v$ r/ J Q8 Q+ ]! k% I- m const mxArray *prhs[]) {6 l8 q8 e2 ] a& x" g+ F( Z& e* f) |
double *a;
$ x) L8 L, d. v# W double b, c;
; \9 m1 E3 v/ R, E x/ N% p( G plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
" ]* \4 ?5 ~2 S) v7 Y a = mxGetPr(plhs[0]);
' `+ X- E- ?8 D I+ A2 s b = *(mxGetPr(prhs[0]));
$ I; y6 i% [" Y* l: e c = *(mxGetPr(prhs[1]));
6 G+ A L- L6 a4 W *a = add(b, c);3 D) K) |/ k0 i) f1 w+ @
} 1 \- R( c! G' m
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:. ~$ }- P) F. V& s: E- b
>> output = add(1.1, 2.2);, q6 ], G* M) R6 ~* v
在未涉及具体的计算时,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 W6 I) V5 i8 U ~& u+ W: M上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。& m' d. r0 K! h1 _" v# `
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
: e D5 e" e: \1 N# i输入正确。如在add函数的例子中,用户输入char array便是一种错误了。5 h9 {* U+ e0 T3 A3 x# `0 \
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
/ B3 C/ |6 q, s. c5 j, V# u2 H2 Y! q) S% _6 a
*********************************************************************************************************************************************
7 h7 l! I2 y- x) J. j6 H) {9 ^3 S, ?1 C+ Y7 Y, A& Z4 C) T6 u
mex 的目的, G. E* p5 X, I7 c7 G- m! @
7 u, j1 V1 k- z7 g$ I2 E P2 D0 O6 i$ J: r通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:
" G# W9 d- v. g! z3 x5 Z
0 [: U; o8 y8 M9 d8 b3 |9 c1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
2 q+ V( x5 M2 i: j
9 w/ }7 O1 q# X4 ?$ E2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.1 n0 v1 _7 `3 e3 B Z/ F6 L
" G) f3 o/ g' [: x; k+ [) ]+ g3、据称可以弥补Matlab硬件设备接口的薄弱环节.7 O$ y' j- s% [8 ]7 L
2 m, M! h+ {: ~& }# t6 |8 Z
今天写了第一个使用MEX.
% s* E' @' g! n1 y
- D# \2 F; y: _* z! R2 {: R一个简单的对Matlab普通数值矩阵的操作.
' T; e" o7 w) I$ Z- k* ?9 O6 F' y; O1 l( [5 ^- A
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
$ h1 s) v# {& w$ T' L' h9 v& _
% v1 c: q' X4 f一律用int代替.. T% n$ ^8 j9 i9 h6 N2 t/ X; k
" p) i1 N. X- V9 a! U2 V#include "mex.h"% y4 g: h# d0 g0 S
#include <iostream>2 ~+ ?; \2 Q( r9 j+ e! E
+ n& `0 ^, y2 wvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])# J, A0 ?9 [: w: R4 s+ j
{! G$ A. q, f) I* U, H* b
3 W& s/ B9 g0 R: R( [int i,j,k;
- |& O% ~; n; d2 s+ [int index;' E% T% H/ W+ q( G
double* pr=NULL;
+ \1 E) [& @' C7 ~double* pi=NULL;
/ z7 h& g" n$ C& A( U, Q5 x) `int M,N;
7 q( }$ Z) d" p8 @# oint ndim;' m6 p( @/ w3 ]( d5 p
int dims[2];
9 W3 g. M2 \/ t: G& R0 [for (i=0;i<nrhs;i++); @9 O2 L5 O' h: D
{
/ K+ m5 ]/ ]1 \# Y: `" q3 m [ if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
3 O5 B" v: K- I {( J; M+ F2 v0 Z6 I. K
pr=mxGetPr(prhs);
/ W `& u+ Z* ?% S6 g pi=mxGetPi(prhs);5 z( _0 K5 H5 y5 E9 l! O3 \
M=mxGetM(prhs);& v; Y) c$ [. D: ~
N=mxGetN(prhs);
. n4 {8 f3 X3 @4 d ndim=mxGetNumberOfDimensions(prhs);
7 N6 R. V3 w7 W9 x; z8 D
6 M2 p8 W! [4 z. | mexPrintf("变量%d:\n",i);
# d. r5 u1 H& p9 A/ R for (j=0;j<M;j++)
2 T9 c8 [; ~/ e. M' f/ z7 C {5 X7 B1 c% O( |) I( p: V* H: \
dims[0]=j;
1 g: N, `5 Y5 U: ] for (k=0;k<N;k++) r% k& @6 l! i% h# b' L* X s
{
+ m r. i$ F0 | dims[1]=k;
6 k/ Y; H! J. Z3 w! j! c" g, b index=mxCalcSingleSubscript(prhs,ndim,dims);
6 C$ S7 E" q5 c, S8 M5 @ if (pi==NULL)0 Y6 Q2 `! Y5 H" M$ l
{
N* z) L4 u& J1 g; @# _" [ mexPrintf("%6.2f",pr[index]);. E1 s, S; `* D* e
}/ m- C. ?: B R
else{, z! F) ]1 Z/ G' y( _: @6 c
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);. K6 q( F" h2 |# U: W7 K
}5 G- e6 G4 @3 p2 }; L$ R8 z' y* M
}
2 @% Q; {3 h' S& H$ D mexPrintf("\n");1 P7 ^, W4 w- w* S3 @
2 `; v2 E& ]0 S' T# W }
5 g0 V9 `* h* L* f8 f+ M1 R
; q6 Q( Q0 b' q g u/ f6 n }
5 I5 {. Q4 j3 p- E' A6 D else{3 h( k& d2 J, l" s2 R* Y/ m
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);4 \7 r2 r$ H3 v, O* Y/ x0 o
}
# z0 S: j6 T6 Q* o7 T, Y3 v! E; n2 N5 [$ i
* A+ Q0 K) _# ~
}
+ T% l8 X7 G. L. Y Z ^' `! x9 W$ ?2 n4 v
}
* l5 n& e( e- w, Z6 z
0 @4 H8 l, |' j7 L" N4 U1 OResult:
' F z# f$ _( F6 x
4 }' G& {: _, L! q>>mex test.cpp8 ~; O1 O2 K3 _3 `# ]1 o
>> test(a,b,c)" J# ?3 J0 Q3 p% \/ {
变量0:/ i3 t/ Z: Z# P5 d
0.35 0.62 0.83
: z/ f m: C8 k3 x0.20 0.47 0.599 ~# T& D5 d9 c. w5 H* ~ k$ B% ?
0.25 0.35 0.55
3 _' {+ T1 @! F8 P; n; M& E# e变量1:% ^2 z; V; h; o6 ^/ @& N% Q$ H
0.92 0.38 0.53 0.578 s" s: E" z2 l& N9 {- v
0.29 0.57 0.78 0.47" Q5 i+ e t7 [ R: j: W$ D, e
0.76 0.08 0.93 0.01
; Q1 g2 V9 \- | s5 w8 q0.75 0.05 0.13 0.34: a' Z7 U7 j( c; \
变量2:' l% d7 S, \8 U$ Q0 ?; P- j
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j8 |1 H6 x6 v7 e x9 r f
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j% c: N4 A& h# v3 P2 K
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
N/ @6 l. H- N6 |+ X( k0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j0 B4 I1 l* V- C4 m
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
& c; L6 @( x4 c, D% ]+ N; H>> help test
- M# }* i6 y, X本程序用于调试mx______函数.
+ b+ n+ i5 J1 A! g1 [; T: l9 z7 s! O: n
/ o1 B4 f4 D V3 N+ a1 u本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html- T/ V7 t% \6 r' X/ f2 }# V' w$ i2 C
# u N8 m& X# Z% M) b$ w下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|