- 在线时间
- 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年数学建模国赛备 |
; X+ [# _% y1 c# W7 P9 wMatlab调用c程序
$ b1 O8 J p" X9 |文章来源:不详 作者:佚名
7 s. X; }( {1 C' Q
) K1 @& J6 R& X9 v# ^--------------------------------------------------------------------------------( t( j Q8 ?. W
2 d8 _. s5 P0 g9 o9 c该文章讲述了Matlab调用c程序.! R5 |1 n# ~0 D7 H) N
8 u- A( l: m( }方法:
; H4 L, `9 K& R/ d2 k/ l第一步:要先在matlab中安装c程序编译器,步骤如下:" E; o$ c7 H9 a6 f$ v4 C1 Y. o; q/ d
键入命令:mex -setup;- L) z: d0 {# {" A9 Z1 e) v
选择c/c++编译器;, d* z- f( _- v% G7 d' z
选择c/c++编译器版本;
4 f. _" G Q1 t: \. Z) j确认。
+ N- h8 f' ]* {- C g N4 G第二步:键入:mex *.c
# r' j3 P. x8 d1 x
4 `+ s; ?6 M# q*********************************************************************************************************************************************
! _! e4 i1 V3 X
+ u; S3 T3 Y* e9 p8 R实例介绍:【转】! B5 I. \, X) `; }4 ~: _0 F5 Z' K" |
4 Z0 ~+ P4 g' m
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:/ ]+ U$ ]" x; `; `- k8 N
double add(double x, double y) {
( h4 e! |: M7 Q( l& m3 k return x + y;, b+ B U+ v( @$ w) e$ B) M/ Y
}
% {/ M- w8 p# v5 L7 i! F现在我想要在Matlab中使用它,比如输入:# j* ~, R# N2 T/ A0 q# B. ?- b
>> a = add(1.1, 2.2)
/ b" A( t! @( O( t* q3.3000- c# Y+ p1 u! c( Y- p- T6 x
要得出以上的结果,那应该怎样做呢?
9 b8 r/ B2 c: F( ]4 ?9 k解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
; |7 X1 p; C; e1 K可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。! N% \: ?" U6 }2 t+ w4 {
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
( q( \) S2 S4 V6 v- R. B比如该C文件已写好,名为add.c。那么在Matlab中,输入:! z- V5 c |# q
>> mex add.c9 c: ]% C" W! g! v' u4 V, {
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
4 T& s5 Q. h1 A5 I0 R+ {我们现在来说mexFunction怎样写。
- |' l( p/ {+ d$ i5 |; T% Q' CmexFunction的定义为:
p: g- \& l' L5 s( n6 I/ K: E: pvoid mexFunction(
1 w0 Y9 @2 }2 h% u* G0 X int nlhs,; @$ |0 D( U6 i0 \
mxArray *plhs[],$ z S; ~, I9 E
int nrhs,
6 u6 `: k7 F: V( X6 ^ const mxArray *prhs[]) {. H; C4 F$ B, ?2 `8 U
0 Q9 s% u! u: d6 Z L0 M
}
3 |# @4 B" N/ g; S) q# l可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:! ~' F! Z$ v( L. M6 ]
>> b = 1.1; c = 2.2;
+ N0 u% H2 w6 @7 l% E" D>> a = add(b, c)
9 F2 F4 f% T4 A: O# k9 DmexFunction四个参数的意思为:. M0 C" N& J5 Z
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。) e& c7 j5 i$ N* x h3 T, N/ [4 G
nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。& w) V4 ]- U5 T1 w \7 u1 U9 [8 c; e
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
3 O" [# W1 M# B: |/ f, Aprhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。5 D/ n3 t6 f6 Z: m
因为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类型的指针数组。) x0 l) R6 v' A4 j% Y4 r
完整的add.c如下:
# e J% X: |- i' C2 }" z// add.c
0 N+ D2 V5 I& M& e' j; c4 `0 V. f#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数/ }+ J5 S: q) q' `
double add(double x, double y) {
~3 C0 z* i5 X- S return x + y;
$ G7 h! w7 r. C& @* h7 f} // MEX文件接口函数
1 y( A2 o- U+ p3 r/ Y2 M! E+ jvoid mexFunction(
8 u5 d3 J# F4 F" c8 X6 @ int nlhs,
2 Q9 c% b3 I/ l9 X3 x, v mxArray *plhs[],& n, |) N' x; O4 Y3 `+ g
int nrhs,5 p2 T3 D" |/ |. f, c. r* n4 w. _ d
const mxArray *prhs[]) {
! b) m8 ?! e" c5 L. ~7 M double *a;
3 G0 j% d5 q& C& z+ L double b, c;
k+ B' I5 y! B, i+ p plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);( K/ V9 i8 `$ _2 O# w% i6 Q
a = mxGetPr(plhs[0]);
8 [$ R; v: h7 H6 _ b = *(mxGetPr(prhs[0]));
4 M O4 h7 Y& j* f c = *(mxGetPr(prhs[1]));+ V3 V* l1 z; L4 G8 r$ s) A1 F
*a = add(b, c);( Q; U9 H2 J: A1 c7 k
}
) x% C1 L( [' b$ TmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
( g; S) ]4 i2 Q+ Y/ Z1 I5 d>> output = add(1.1, 2.2);
! x* Z8 y; ^/ P1 y! D3 l+ F$ w, J在未涉及具体的计算时,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便是已计算好的结果了。
' N7 v: y8 t$ q上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。5 y4 f. n" s: I9 ]/ G
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
' U: ^6 j, F7 {, G) @2 g输入正确。如在add函数的例子中,用户输入char array便是一种错误了。' j+ Z4 I; [$ R' ~' Q5 h( b
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。' \* v$ M5 x0 T: p" E2 x4 E- `
! j, V0 r7 w' o; j6 ?' v*********************************************************************************************************************************************) o a9 P6 v$ {( p7 M& G F/ Y
) R- q' m7 X* c. n" O1 N8 i, i! w3 u
mex 的目的,* }- M" i' s) N4 L0 r
! @: K7 k+ E( X通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:
8 P2 D# T* w7 O7 `1 g
) @5 p9 e6 V; F, v5 j% \1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
$ C y5 I1 z2 f: c9 ~4 o( ~- G0 Q# L) @7 q; A
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
( V) r6 g- v: t! O F
6 p% q- @' C; f; o7 f- s+ s3、据称可以弥补Matlab硬件设备接口的薄弱环节., m) C! }! r4 |: r6 y; u
5 l- G' A2 T: ^* F" [5 L* z今天写了第一个使用MEX.
9 m/ F: n2 [, G; t, \2 v3 j/ a: u' [4 R
一个简单的对Matlab普通数值矩阵的操作.
3 V" Y/ D: \# ^' S( b. C) @1 \. u" ^4 Y, g# | i) v
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
; O9 G/ x5 h6 j5 r1 l: X1 d! E( i) e0 k/ I: G( ?" e* C3 \5 }: `
一律用int代替.
}, ~. y k5 ` r; V
: h9 N3 U. ?& m$ E2 Y& T1 r2 S# r#include "mex.h"
7 n% l" I) P2 F/ r) ?#include <iostream>0 F# [0 m& j9 O) T+ B6 S8 r: u
1 x( I: R; Y9 `void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
# Y. Z9 f- F; O( L/ o3 ~{
) X& h+ l0 b( q1 v% I Y" {4 Q& Y3 l H$ C- K
int i,j,k;
% Y2 q' W. d5 f8 sint index;
: `& P. n9 y0 D: C0 F% ]% _0 jdouble* pr=NULL;
5 f. J7 L) X9 Q# t0 D- j! j0 gdouble* pi=NULL;0 V5 W- _5 M a5 j
int M,N;
- D( Y. U* }5 r) D6 tint ndim;! }# E" x- J0 b, y% f$ i" D
int dims[2];
; c4 q4 L% j- @' Kfor (i=0;i<nrhs;i++)
/ U9 _$ ~9 O* ]{
/ G4 w6 w, |" `: W0 J7 l6 @ if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
7 U# ^' p* n2 q/ v {
`% h; k6 [7 O pr=mxGetPr(prhs);
* ]7 W3 x+ y+ ^# _ pi=mxGetPi(prhs);
, L) g0 o% u6 u% s' ? M=mxGetM(prhs);6 F7 G/ h7 O; Q: k8 D2 x8 Y/ H
N=mxGetN(prhs);
1 y; x" K3 C" k7 H ndim=mxGetNumberOfDimensions(prhs);
~+ J; Y7 o, q7 V# L$ k. D% f( f: `" g/ o/ |
mexPrintf("变量%d:\n",i);
. k0 @. b9 V7 ]$ e9 \ for (j=0;j<M;j++)* q% j+ f x& `$ N; B8 n# V# @. t
{. f, O$ c+ d1 h4 A3 L
dims[0]=j;
) U% v! o% u5 |! }" F for (k=0;k<N;k++)$ d3 h" `: `: d7 h* c
{
9 c3 v) E$ \$ S) ` dims[1]=k;
2 y% N, z. Z% K" M3 T2 l5 q index=mxCalcSingleSubscript(prhs,ndim,dims);. S6 ?1 D; E5 Z! q5 `: o# h5 R
if (pi==NULL): g$ @7 d8 T4 t: Z9 |
{$ r+ ?7 J T+ q5 C
mexPrintf("%6.2f",pr[index]);* |# B0 n" M$ A% M
}
3 y2 J1 `, Q3 a else{5 _3 I3 f X0 {5 p. B$ e2 L
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
6 A" q- T9 R. d6 r0 |" X }0 z# S6 M' H) Q. c% G8 T
}" |: P5 ?/ L1 j+ m3 ?
mexPrintf("\n");) w& S2 y2 S8 ^: M- J# s% S( Q
) e4 T1 W% M5 |1 _/ r
}
1 z6 C E* n- i 3 g! e& Y9 `9 j3 {0 F' Q/ J3 z
}$ S+ }& `5 I* s% ?: v) `2 k
else{ y, G5 A/ Y' ~ j
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
" [5 x: W' n2 e9 [) Q6 }}* U8 S6 i. f9 ~! k, R ~) ^2 j
: i$ o) r9 G9 B4 D1 l( `% \' x6 a8 L0 q1 \* E! {% J6 } \) g) C
}7 s, u% a2 v4 [6 K; k$ W! O$ [
) e; }4 z' `! L2 p}
) X5 M+ H$ o, Z7 X( V
$ n/ K4 E, N5 g3 R1 h* x% D) yResult:6 s# L* Y. h {( t3 k( j% v2 K% a* K
3 D6 t3 S5 v% O5 M) j
>>mex test.cpp
. @2 K) B0 f+ j0 V( U3 C>> test(a,b,c)
1 e8 P; T. Q) H- f& ?1 t变量0:# G9 h: Z+ q; E' @- I2 x) q7 z, z
0.35 0.62 0.83
1 P' C$ U$ ?: V# Y, c# |0.20 0.47 0.590 V* k! x+ W& R( ]% j7 X# v5 q
0.25 0.35 0.55
9 B2 m a+ N6 }2 ^+ G u变量1:
/ _1 {& N |, ~* Z( w% N0.92 0.38 0.53 0.57
' ~" ]# j' y' r! T9 S9 T" m0.29 0.57 0.78 0.472 |+ e/ V- D% g3 k' A2 i6 A! M
0.76 0.08 0.93 0.01& V I- m7 S: v/ U: F% Q. f) B
0.75 0.05 0.13 0.34
* f: E6 Z1 |. v& F" G变量2:
2 L7 d# t- S# m* I9 L* [0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j1 h Y0 }6 ]8 A+ ^6 l4 m9 Y
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j$ |% Z/ @; f' O* u8 @3 E7 }9 V# l% y
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
+ e$ M6 W* t; Q0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
5 C5 x8 Q7 @+ e8 l0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
2 [# i; [0 Q) _& M* \>> help test+ r/ E7 F4 V+ |' l6 N; N
本程序用于调试mx______函数.
; u# N1 V, B! L0 a9 G5 Z, U6 x
* T3 D* A3 g" r4 f: t8 a
# D5 b9 F5 }4 q: v- Q( z3 L+ x本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html. N# \! q; \# s* f5 A) e; d( e
& f- O& T% R7 t4 T# s' L
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|