- 在线时间
- 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年数学建模国赛备 |
3 N h8 Y. ~8 O
Matlab调用c程序
" v U) @5 c+ Y6 u) a文章来源:不详 作者:佚名
+ I% O+ f. ?' [2 z. O! s7 Y& r. d* i; ~1 }" `. Q, H
--------------------------------------------------------------------------------
2 j0 G) D& q# o: k6 g/ L
% D# x9 K4 t- }1 M该文章讲述了Matlab调用c程序.+ ]' {2 R1 y: a2 P& y1 `) p
5 a" m$ H y! _
方法:2 g; J/ O; s* t/ \
第一步:要先在matlab中安装c程序编译器,步骤如下:+ M9 L1 c" t; P
键入命令:mex -setup;
& j4 g0 I1 f8 J选择c/c++编译器;' {. j9 M8 U9 f/ O" L/ k" Q8 \& z
选择c/c++编译器版本;7 W" ~- s5 H- L7 {
确认。% S& V( |3 L- R& x
第二步:键入:mex *.c. S7 x0 b! k% c4 |( ?# r2 y
0 K9 D4 V1 _5 O( ^0 c- P: d*********************************************************************************************************************************************
3 z% @( L3 \5 [! m; I% q
7 e2 Y! K! X X' ~$ I5 o实例介绍:【转】: ]8 c! ^9 W6 ]1 Y. |" D
/ B* @: @! }# Y- X
如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:7 ? t# z1 D5 V9 [/ y" }, Q
double add(double x, double y) {
- a5 j% @$ X! i0 k$ ~ return x + y;
+ R) ]3 x; Y. o+ d$ t9 k9 d}* r9 y v3 u# t
现在我想要在Matlab中使用它,比如输入:
& h9 n, Z5 I, B% O>> a = add(1.1, 2.2)) r6 w$ y# b6 [
3.30004 [: y# {' v7 w/ _. ~! H
要得出以上的结果,那应该怎样做呢?
! H; n) F+ z& s5 g( |1 D解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
( ^& m/ \' W6 D可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。# W5 a* \1 Z2 d- F
所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。5 n: v* {* Y. x f
比如该C文件已写好,名为add.c。那么在Matlab中,输入:
- P- ]: `6 J u/ R>> mex add.c
0 c# q! A) c9 R4 O5 |就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。# q% ]* s2 `, d7 ?
我们现在来说mexFunction怎样写。
9 A) ?( s% n' j& m0 PmexFunction的定义为:, ^' R+ b! E* R: V& ^# L
void mexFunction(4 `$ h, y9 _* q, |' n! [/ l& U: t0 b
int nlhs,
8 w: k! o' V1 k" @. y mxArray *plhs[],
+ t0 _ N+ @$ `4 r* t int nrhs,
1 t! _ f' \0 U, }. I1 h const mxArray *prhs[]) {
7 h6 d9 `8 v3 p& a# w7 s/ P. @+ Y M. b7 D1 }
}
+ c# T; ~4 v$ K2 \可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:) t& g+ I- P) B; B1 ~8 @
>> b = 1.1; c = 2.2;0 N7 U, [2 I3 y1 B# M
>> a = add(b, c)- H) H# a! }+ q2 n5 U- P1 A& ]) f
mexFunction四个参数的意思为:
# D1 t+ x `1 r9 Bnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。/ A* w' M9 N2 P. s V; f
nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
+ v7 O0 k# b" z! r9 s% @+ W2 Z! s9 Tplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。% ]4 G% a4 C: ~2 v
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
+ ~5 g$ F) g& Z0 U( w+ t因为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类型的指针数组。
5 h, \" q: K1 V6 c- ~% ]完整的add.c如下:, t/ H8 M3 K8 F7 K3 L
// add.c' V/ a+ w7 H2 {: _6 ^
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数3 h, H' N S% R
double add(double x, double y) {
0 W% n8 s9 x/ y: K1 ^+ b return x + y;
, d! `; r+ Y: s _+ d} // MEX文件接口函数
3 ^; c. \" b9 c0 X- T6 Gvoid mexFunction(
% U/ S9 o& H" I/ R- W/ V# N) E: ]+ c int nlhs,- B8 R2 N) s) t( B/ y# s# r9 v
mxArray *plhs[],
1 e7 ^0 F) U; c' ^. w6 b int nrhs,
7 O: S2 \ l6 d( z. e5 M' V' d5 t const mxArray *prhs[]) {
* A! p" P) K* I+ n* m double *a;0 K2 X& U; ]& H: ~/ j% L" I; D( I
double b, c;
( A) `! x4 H' \4 L5 J* f& z plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);/ L- {5 O+ k2 m9 E5 G! W
a = mxGetPr(plhs[0]);5 ~; }! k7 ~* z0 W8 c# W% ~
b = *(mxGetPr(prhs[0]));
/ t- e# Y+ ]) ~" u! J' V Q c = *(mxGetPr(prhs[1]));
- |! s9 m( [, U( B. i7 a' y *a = add(b, c);7 @+ J- H5 c$ d3 ]7 I1 |1 k& Z
}
- w4 Y+ x5 \8 [mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
" J( S* ?* D i) U! ?>> output = add(1.1, 2.2);. Y) l5 F& d; k3 T8 I3 o4 D
在未涉及具体的计算时,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便是已计算好的结果了。
3 l% R- `9 a3 y2 b. u上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
% a5 k: n u: X- @% T+ T& C+ ?/ t实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
Y, b4 M0 J: `( A& z6 e输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
: E3 o. ^/ Y8 B' v, j9 h- T从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。, ^9 ?7 k" M$ x1 ]! c) {5 ^
2 [7 X5 r2 e+ ]" q1 O*********************************************************************************************************************************************6 W9 I$ i, F0 @, Q6 O
) s- t% d& O( ]mex 的目的,
* A6 p Y& I! ^ K/ [# V" W$ A3 A9 t, A" {, x1 {2 `9 q. w+ r( ~* \
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:
3 c( z9 }& F/ x6 I3 I* s( f5 V9 H
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.
9 v) J1 D3 @2 ^5 u& ^9 v4 `6 h* _7 ?% `, N
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.
* r! I" F' H" i4 A, a. O
e! n+ _( Q3 p: A& g$ V) Y3、据称可以弥补Matlab硬件设备接口的薄弱环节.
2 o3 p# j- P2 u- Z x9 ^+ x! H1 z& b' r: O7 V
今天写了第一个使用MEX.
6 p9 v7 Z+ v& G2 O% ]' F [7 C
0 D3 b3 ?1 c) d, V- z4 m% m+ A一个简单的对Matlab普通数值矩阵的操作.2 q- q: f( g( }
) J% ~1 k s" }' q' T. j- z
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
" u0 u1 _0 O9 |7 `; m+ o- q" X$ @1 u
一律用int代替.
" P1 b0 K) g0 e: M2 h
5 w+ f- \" g8 O* _- [! M" k#include "mex.h"
( n9 ~% p/ s& A E& p#include <iostream>
$ ]9 }( q5 D9 y2 H2 Q. _" f" p( e# |- l. c' U0 F' l
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
5 ]7 f7 V& B$ J# a# f2 s% s{" F, A- a: [6 b, n# w7 ?
/ Q9 C# \2 q4 R# Mint i,j,k;
, x9 w" \* ~, e6 K7 Pint index;
) U/ W' E7 v5 T' e( p% |; ~- Xdouble* pr=NULL;# @0 d' r; y% Z, e! J( E( E
double* pi=NULL;9 H% J; G( X1 F
int M,N;6 z3 l- G4 M9 |6 ]! ~
int ndim;
6 z, w2 F' G! M" ^# ~6 Bint dims[2];* i+ g- K N$ b- q
for (i=0;i<nrhs;i++)
& R9 M. n8 ?: |& L/ Z6 u% ~{, x( P8 P' m" F, Z; J4 p* `" t; b
if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))1 @# H1 S% L+ M8 D9 {2 A3 j
{4 ^/ \8 D! N* s7 S* b" a# b5 Z
pr=mxGetPr(prhs);
9 K& }& |" H% O- E1 ]' c, D& _ pi=mxGetPi(prhs);0 @$ s2 T, q! {
M=mxGetM(prhs);( g7 i R: {6 b9 a+ v
N=mxGetN(prhs);$ K3 c+ p5 @+ T
ndim=mxGetNumberOfDimensions(prhs);7 P2 q. _4 Q& n2 a
( |7 m6 I6 j& p- a* @7 u- N
mexPrintf("变量%d:\n",i);
8 C7 z) R. O! k& X for (j=0;j<M;j++)1 ?) q8 u# S. `! h, z" ]
{
& ?- A: r! j: v* d1 s3 {+ O dims[0]=j;
: d: F3 Q: Y; }* [1 M- a for (k=0;k<N;k++)7 [# w6 x- t0 U; p% y Q
{
5 Y7 I6 ~$ Q& u$ r: V9 {; i dims[1]=k;5 s: P2 a% f0 ~: D& N$ C' o2 P
index=mxCalcSingleSubscript(prhs,ndim,dims);
! Y- w7 b2 i4 S2 A* Q L1 I if (pi==NULL)
' Y* I; x8 ^, d9 v( f# ]# G {
( {; \* d& j! y; } mexPrintf("%6.2f",pr[index]);% W! O. K7 p9 Q2 W5 a5 J( l
}4 w" u; X! R% n) o
else{
; h6 B% t9 j. M o% ]: X7 K# @8 z mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);7 [& `0 R- l( R0 T' ^
}* D- S% |, a) C/ w0 Q( t+ N s
}5 H q5 t8 q& C) A; U% S- U: X
mexPrintf("\n");
" i' Y \; U* L* a- W6 t7 P6 u5 x9 ~! G' h5 g& q! x8 j5 d8 J
}
; j3 j. z2 g" x9 _$ T7 l, d
( w( v6 o h; ]/ P5 X6 n }
~1 @$ V, [& P3 I0 e' K1 c else{6 q0 v6 e& ?6 }# T
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
2 i8 D) G H* q8 d. x" G}( D/ y$ J0 l4 `" a* k; N" N R) k
, R X" M" ^, K* H9 {
3 B) Y8 C' `1 }. E% F Q. h+ M3 t
} S; r% F. t0 S# C+ i6 s9 T) ^
1 \3 x) T7 }8 n) n! ~' {( J! O
}
; u' o6 N" h" r$ w: h4 n; F U
" p( X3 R4 @3 w% U) O: \) aResult:
) p- W2 \1 C# S
" }- S: w. T @2 A7 G9 D, \% \: {1 h, Q>>mex test.cpp
7 N4 h) ?& b8 x$ P0 U>> test(a,b,c) n$ R8 z( z3 R5 f% M# C+ M& N
变量0:% Y- i F" c2 L
0.35 0.62 0.83) U/ q2 j1 p5 ~0 B2 p. E: s8 P
0.20 0.47 0.59
* L8 }& ^- a$ _( H9 p d0.25 0.35 0.55
; y9 G/ g: O/ o变量1:3 E, x* j0 [; T
0.92 0.38 0.53 0.573 R8 D% \% {9 Q) K1 ]/ w
0.29 0.57 0.78 0.47
% E2 J p% T/ t+ V2 [0 A0.76 0.08 0.93 0.01
+ F2 @: y. s) i0 p4 S a( F$ q1 u0.75 0.05 0.13 0.34. ^3 ]2 M; c" f( v5 f
变量2:/ K2 R: d9 h, D Y3 H
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
+ r* x7 H1 I2 C6 T3 i/ x0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j* W8 V! |( D) `0 O% r' Y3 C& d
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
( H, F2 F, C( C8 N# x7 U5 C0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j( i ~' l+ @( h' z! R4 K
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j; O, x+ I- n7 K# G) a
>> help test
p- O, B i7 z: `! k+ N0 w# }7 a本程序用于调试mx______函数.3 U1 c* Q \, h) B# _8 l R C/ ]3 F& j
: P4 E2 w6 G/ B9 t5 I/ `
+ ~4 u7 u0 ~# R* b! j" ~本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html; D( j& N+ l# @& e1 z" ~
' U g0 [( |# g6 B) n" {& c1 |下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|