在线时间 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年数学建模国赛备
) j2 K; h# S% n9 L7 ?( P# S
Matlab调用 c 程序
0 x/ k+ n& V4 ~ 文章来源:不详 作者:佚名 # p6 N1 `$ B" e5 A/ Y
! I6 L: b ?4 p3 r" J0 p8 X+ k( R
--------------------------------------------------------------------------------
: c& p3 d1 L/ ]3 K! Z0 r
0 E, s$ A$ n) y7 P0 e( A S 该文章讲述了Matlab 调用 c 程序 . % Z) Y5 D2 G, R; }+ y* D
- Y( D5 S" A# H, ]" v 方法: + ^. c7 e. `1 Q9 h: t5 U
第一步:要先在matlab 中安装 c 程序编译器,步骤如下:
0 @4 ]/ x6 A- _ 键入命令:mex -setup ; " w! c* x) W9 u! i/ v
选择c/c++ 编译器;
% T4 w0 d; e* V# l+ ]8 q 选择c/c++ 编译器版本; 1 }' i- q' r3 O' ~; `
确认。
7 X3 ~) X/ F5 V+ v( U/ ~ 第二步:键入:mex *.c 8 X5 P( }* ]" N. u* `# Q/ j% w! {
- ?/ g7 h- ]1 U/ \/ o7 X
********************************************************************************************************************************************* , i; {) }7 g8 O* N( |
6 h# S0 G2 G! b! h 实例介绍:【转】 9 t% J C K' ~1 s Y1 F) p3 E
* Q) u! ~0 u4 K, a# i; Q
如果我有一个用C 语言写的函数,实现了一个功能,如一个简单的函数:
5 ~! W" T% O7 I$ J# [; D$ i double add(double x, double y) { 2 R- f' }2 |3 ]9 D9 J
return x + y; & M$ } O, [6 I' k
} 8 b+ n+ `4 o- W* u
现在我想要在Matlab 中使用它,比如输入: $ z* z; z5 D" Q7 F
>> a = add(1.1, 2.2) 0 t0 Z5 d9 U8 H1 G5 ]. i& N
3.3000
2 I# I, s/ L" \. _5 h 要得出以上的结果,那应该怎样做呢?
4 n# i9 L1 K" i3 N, ~6 u. f 解决方法之一是要通过使用MEX 文件, MEX 文件使得调用 C 函数和调用 Matlab 的内置函数一样方便。 MEX 文件是由原 C 代码加上 MEX 文件专用的接口函数后编译而成的。
: X: t) B9 i5 K/ X4 ]5 r* F1 L, n* [. Y 可以这样理解,MEX 文件实现了一种接口,它把在 Matlab 中调用函数时输入的自变量通过特定的接口调入了 C 函数,得出的结果再通过该接口调回 Matlab 。该特定接口的操作,包含在 mexFunction 这个函数中,由使用者具体设定。
1 c$ g8 i$ v/ ^ D! v7 n 所以现在我们要写一个包含add 和 mexFunction 的 C 文件, Matlab 调用函数,把函数中的自变量(如上例中的 1.1 和 2.2 )传给 mexFunction 的一个参数, mexFunction 把该值传给 add ,把得出的结果传回给 mexFunction 的另一个参数, Matlab 通过该参数来给出在 Matlab 语句中调用函数时的输出值(如上例中的 a )。
1 a4 h" b# }% C0 t) t/ ~% e M 比如该C 文件已写好,名为 add.c 。那么在 Matlab 中,输入:
& ]5 N$ x1 t/ [9 l: g >> mex add.c 1 A2 [' h$ b# k9 V+ `
就能把add.c 编译为 MEX 文件(编译器的设置使用指令 mex -setup ),在 Windows 中, MEX 文件类型为 mexw32 ,即现在我们得出 add.mexw32 文件。现在,我们就可以像调用 M 函数那样调用 MEX 文件,如上面说到的例子。所以,通过 MEX 文件,使用 C 函数就和使用 M 函数是一样的了。
$ a* N2 C8 |/ `, [0 X 我们现在来说mexFunction 怎样写。 + n; ]* s" M( h% f
mexFunction的定义为: . Q9 m. E5 Y( _, U$ B& z: E
void mexFunction(
; [( Y8 [; H9 F& A; z( y int nlhs, - T- v, C7 [) P% h
mxArray *plhs[], ! {9 g3 K, u6 S$ P6 h
int nrhs,
. F4 Q, U4 p) k8 \3 P9 X8 @& V9 p const mxArray *prhs[]) { z3 I( i: ?+ S5 L$ h, \
& R/ N3 e: O; I9 x6 b8 [. \/ j. X
} 5 _9 J9 O5 v8 ?! a+ C7 t" y
可以看到,mexFunction 是没返回值的,它不是通过返回值把结果传回 Matlab 的,而是通过对参数 plhs 的赋值。 mexFunction 的四个参数皆是说明 Matlab 调用 MEX 文件时的具体信息,如这样调用函数时:
& c: E% y" o6 Q" i; F* Y >> b = 1.1; c = 2.2;
+ h+ O$ y F2 Q1 A >> a = add(b, c) 2 o) T. D. a( V* ]& l
mexFunction四个参数的意思为: 4 {$ K. V* D1 [; N
nlhs = 1,说明调用语句左手面( lhs - left hand side )有一个变量,即 a 。 / d' ]- c1 f% n( }# D
nrhs = 2,说明调用语句右手面( rhs - right hand side )有两个自变量,即 b 和 c 。
) E, b9 N/ u/ C, L2 |) P% \: T) P plhs是一个数组,其内容为指针,该指针指向数据类型 mxArray 。因为现在左手面只有一个变量,即该数组只有一个指针, plhs[0] 指向的结果会赋值给 a 。 ; E D1 i1 s: E: P. q/ I; b2 o
prhs和 plhs 类似,因为右手面有两个自变量,即该数组有两个指针, prhs[0] 指向了 b , prhs[1] 指向了 c 。要注意 prhs 是 const 的指针数组,即不能改变其指向内容。 ( L3 A, M4 t7 }
因为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 类型的指针数组。
& \7 m$ ^: C$ s( S3 y8 K2 _ 完整的add.c 如下: " @( G' ?! V8 v9 _+ F7 ~
// add.c
O- f) o: O2 r3 W7 Y7 E' P7 f #include "mex.h" // 使用 MEX 文件必须包含的头文件 // 执行具体工作的 C 函数 0 B9 X4 m& l7 Z" i7 p& k
double add(double x, double y) {
% K H: n, N* y- W/ E( o/ ^1 y return x + y;
: Q2 \( O- U8 B; D! {' I6 B; B } // MEX文件接口函数
/ B1 x9 S0 B$ g0 c# w5 T1 C void mexFunction( " N- z; P! E, W; R% r* v
int nlhs, . Q: L$ S) @. x' ^- O8 R
mxArray *plhs[],
3 { ]) T% M3 o: b) {$ ~ int nrhs, 6 Y2 R$ x1 K9 h7 c3 I) X; p
const mxArray *prhs[]) {
# i; i. r3 V/ o: a* ]) e& o double *a; . X. z0 D6 R5 s4 ~6 p
double b, c; 5 c0 `- Z& k, S6 i
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 3 D# d. l* M2 N$ z8 t
a = mxGetPr(plhs[0]); 5 C7 M: {+ @5 |" V6 I
b = *(mxGetPr(prhs[0]));
3 m, _- f4 }* ], ^ c = *(mxGetPr(prhs[1]));
# O% _. }# y3 l+ h( y K5 g3 V *a = add(b, c); 1 q9 f! ^2 R" g( f8 @/ Z U
}
5 e7 u) |1 {6 C* p mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
8 ]3 R1 H/ T- F, H2 k/ @$ Q >> output = add(1.1, 2.2); 8 w. f$ ]- h7 @8 E3 I8 ^- V# I% R
在未涉及具体的计算时,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 便是已计算好的结果了。
4 g* g7 _! t. j3 r6 I( A, R& S 上面说的一大堆指向这指向那,什么mxArray ,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
. J! ~. P/ p9 \( s 实际上mexFunction 是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保 1 g( l2 u- e9 `* D7 V' M# s
输入正确。如在add 函数的例子中,用户输入 char array 便是一种错误了。 * C# [: k$ Q8 u3 Y2 U+ d/ ~ Q
从上面的讲述中我们总结出,MEX 文件实现了一种接口,把 C 语言中的计算结果适当地返回给 Matlab 罢了。当我们已经有用 C 编写的大型程序时,大可不必在 Matlab 里重写,只写个接口,做成 MEX 文件就成了。另外,在 Matlab 程序中的部份计算瓶颈(如循环),可通过 MEX 文件用 C 语言实现,以提高计算速度。 - I* ?$ @+ z; h$ |
6 h! I5 t* s0 y. o. I8 O
********************************************************************************************************************************************* 6 `3 Y# g( @7 [7 k5 E, o
" P; k* f' ~% c8 B9 d mex 的目的 ,
3 v* r" k" d9 S6 h7 R9 W) Y 7 d; l. D6 U4 }4 a p" n. r8 ?
通过C/C++ 语言编写代码 , 在 Matlab 中将其编译成 mex 文件主要可以做以下几方面的事情:
$ c( w+ Y, R" a. x5 a7 J3 D: J7 a , y/ e) c3 p" h# J! A
1、加快程序的执行速度 . Matlab 在 for 上如老牛拉车的速度确实让人抓狂 .
8 L5 U: T- a3 ?! E) Z3 e 5 i+ i7 P/ s8 n5 A' y+ i
2、将 Matlab 作为 C++ 的开发调试环境 . 尤其是有大量数据需要处理时 , 用 Matlab 观察其中间结果十分方便 . / {* s5 @( x+ J, K4 ^& u! h
0 G4 G8 d8 f8 Q& d1 H1 @ 3、据称可以弥补 Matlab 硬件设备接口的薄弱环节 .
$ \' D! G Y, J$ `
+ Q6 }& K" [$ J! w" u; Y 今天写了第一个使用MEX. 7 w+ n- k( N1 V0 b6 P& B9 e
( {/ [) \9 t/ g3 u0 X 一个简单的对Matlab 普通数值矩阵的操作 .
! i! B6 d' O- p( H. m# S / l2 S; F6 T& o0 b$ k% x6 l
其中Matlab 规定的与操作系统版本有关的 mwSize,mwIndex, size_t 在 32 位系统上其实本质上就是 int, 所以
# }+ x$ Q; H+ c% F " m' x+ A3 v. d5 m( j) M
一律用int 代替 .
y& W( Z) u: R: m Q
( w1 C; U+ T% p0 v7 z #include "mex.h"
0 Q1 w+ i8 D8 w& {- m9 F #include <iostream> q" R" B5 K- u* }
% Q7 _% Y6 o B# ~$ x' h void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) 8 y) E) N Y3 U
{ 0 z3 |; [) Y3 U$ z
* i' `' t% l1 ^, H int i,j,k;
7 A* N0 a/ u! T* a& K/ W int index;
3 Z p( _: O: [8 _: g/ u2 j double* pr=NULL; $ N- Z8 Q0 ^8 a8 d- F; F
double* pi=NULL; 9 z" p* ~% ~) N |/ W/ x* L, `
int M,N;
: o4 T( `' ~! L" g( n, ~" B1 ~ int ndim; 4 f! T e( R5 g. E* z5 R
int dims[2]; & `3 R. @% `9 z: C! R
for (i=0;i<nrhs;i++) ! Z! _# W9 R, T M" j
{
5 y9 ?% f( K4 r1 J if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
$ ^0 _# _/ g0 { {
. r$ n3 i1 q/ x pr=mxGetPr(prhs); * L6 x. n& {9 L5 ^! T# z4 L
pi=mxGetPi(prhs);
4 J4 W! W% h+ J* F) o2 o M=mxGetM(prhs);
# z0 ~- @1 D! p+ S0 [8 E N=mxGetN(prhs); + U; U3 F+ T% o7 e+ j
ndim=mxGetNumberOfDimensions(prhs);
5 q& _ c5 h/ ] ) [ F J7 y0 z4 @/ e2 d. Q
mexPrintf("变量 %d:\n",i); + T& C; W# j) L% ]0 z/ a3 e9 l
for (j=0;j<M;j++)
" h3 Q* y* u% U { ; F0 w. E2 `' v% i
dims[0]=j; : |4 m8 l E" f8 B& Z
for (k=0;k<N;k++) 2 v8 b9 i+ a: i
{
* b; r; Y: [2 G: A" G5 U' L& s6 n dims[1]=k; , s% `- G# K6 U' s- y
index=mxCalcSingleSubscript(prhs,ndim,dims); * d2 x. v# C7 N; o
if (pi==NULL) * ]( x0 e: Q2 M. n/ h6 j& w
{
; o0 ]" @1 F2 M3 e0 N8 m, b mexPrintf("%6.2f",pr[index]); * U1 I. m8 }3 ?2 r+ E" ]" U
}
. G: v. _/ ^* |: { else{
+ h9 H" x6 w- ^* ?2 w, I$ a. A mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]); 2 t9 D2 G ~1 ?- A
}
5 p; ~. y1 x# ~, t. v& V8 N E } / F: `, i0 j' B+ X
mexPrintf("\n"); * f; u e4 F! g2 V( u
; ^$ x; r. y/ L& V2 J( h
} 5 J+ R5 a+ \, \, d! p* A3 u) P
9 C/ r. g3 s5 @! d } ! E6 k. e( a) x' E7 j" v+ q) O# s
else{ 8 I3 `- V' C0 i* N: H
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i); 7 f: p# r1 o6 x- I( b+ m
} . L/ m7 V3 R1 h+ F4 f' U9 R
/ w( F1 P- p3 T, L ' M& }; j: v. P5 I- ~8 ~1 p
}
4 {8 R7 T! F R9 E0 @' e1 x4 {
& y. q. T; Z" C: q5 E3 w } + j- K# c$ f& a/ n) S7 Z! \4 {
5 i+ F2 y+ \. P
Result:
7 W6 d+ _! K: i% O2 q
, _6 [1 R& ~7 f' K >>mex test.cpp
& B! T( P( a1 @, t9 G0 R1 M >> test(a,b,c) . X( b9 u9 E* R1 y( w% e
变量0:
8 m8 u6 @7 o7 \5 Z0 v2 h 0.35 0.62 0.83 8 ^( ~- Y9 O- h$ S: j" X7 R
0.20 0.47 0.59 4 v: Z% [6 N2 _: V; `
0.25 0.35 0.55 ' J% k$ p% [- |* P* z
变量1:
* b4 v$ J0 z1 o W8 m 0.92 0.38 0.53 0.57
% P: F" @! ?2 t5 q0 k& e8 t 0.29 0.57 0.78 0.47 " f6 M, Z- r# i
0.76 0.08 0.93 0.01
: U$ u @3 {/ \1 s8 K, s. f4 E 0.75 0.05 0.13 0.34 : M' w9 m- I" ]# e4 U2 s; i
变量2:
9 s$ S) D+ o8 [4 h5 d 0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
9 |+ G. n( g$ z N I& G 0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
3 Z2 K- k6 l, D) M& R 0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j ( |2 j3 J: L) ^
0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
8 I9 t4 v. N; Q2 K7 |* g 0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
- }8 N& v& V, K+ P3 J% d2 [* E >> help test
! l3 V" R% a7 T, X! P2 c0 V' [ 本程序用于调试mx______ 函数 . + D$ J, E& Y3 b! D8 p
2 }4 M/ G# Y' w
8 F2 e4 v5 ^# I9 I# P* B 本文来自: 高校自动化网 (Www.zdh1909.com ) 详细出处参考 ( 转载请保留本链接 ) : http://www.zdh1909.com/html/matlab/14744.html
; d% `! S3 Y% g6 L+ |8 M* s
9 K( }1 C8 V' b, `% s 下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
zan
总评分: 体力 + 5
查看全部评分