- 在线时间
- 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年数学建模国赛备 |
- ~7 Y, F! ~! z
Matlab调用c程序+ U$ Z: _9 w+ ^; r* R9 a- J+ Z
文章来源:不详 作者:佚名 ' U; P. S6 v; U+ V3 t1 i
6 E8 D6 Q9 e; @( \+ k
--------------------------------------------------------------------------------. s" R k3 [ F4 y
9 U4 P w& ^' [( L' c! T, J) C
该文章讲述了Matlab调用c程序.& ^) ^' K& O2 N! O: {7 w
5 T. _$ q# ]: ?; y3 C* r方法:3 c0 E8 M P- i& x0 Y0 K
第一步:要先在matlab中安装c程序编译器,步骤如下:
1 h# G- K& i# h键入命令:mex -setup;, r4 U7 t$ Z& l, K9 ?9 u
选择c/c++编译器;1 e, h& a$ u% x; x% m: ~
选择c/c++编译器版本;# P8 G% Y7 V* a7 E. ~# m' F
确认。
7 ]3 T; N' Q6 U! k& S Q1 L6 x第二步:键入:mex *.c2 s9 Y4 T; Q: `# _
1 L3 ^3 b/ t; g2 m: E*********************************************************************************************************************************************' {4 B9 K O+ E% \8 Q% a; @
" D* o5 X$ t2 v. Z实例介绍:【转】
6 q# u/ t8 t2 K
' m; b& w8 j* g2 r3 j5 B# u' |如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
- u7 o$ D$ D- adouble add(double x, double y) {
6 Z8 @$ a1 g+ N' G' E return x + y;& Z0 `/ V" U' K8 I: e) c# z
}8 G3 X, R; o4 b2 I( G) U( ~% C8 L+ x0 s
现在我想要在Matlab中使用它,比如输入:. ~. M& U/ I% w* V7 {
>> a = add(1.1, 2.2)$ ~% n; v7 L* O& [# H
3.3000
7 M' m$ `% d) K* p/ v. r要得出以上的结果,那应该怎样做呢?- W& R; \. a5 ~! d
解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
' ?4 |7 X3 `: p' _* L0 b可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
& R% M9 ?2 a3 n! J# ~2 ^所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
2 T8 k; W5 E, F比如该C文件已写好,名为add.c。那么在Matlab中,输入:
' X3 _8 M. \/ A4 u# V>> mex add.c# O6 d, m1 j) s d
就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
( D2 e, }+ s1 `" s2 G我们现在来说mexFunction怎样写。! s9 s& d0 d1 a) x* L6 G* N4 o9 E
mexFunction的定义为:
* \. o& U; }' j6 o5 L& Qvoid mexFunction($ G: n5 `' N6 Q/ D
int nlhs,1 O n( T' f( S: T) e3 l
mxArray *plhs[],
! s/ A, J% W% d5 M int nrhs,( [; w D3 ]8 j9 n% i1 g9 T
const mxArray *prhs[]) {
6 l" S1 f: O& K$ y. Z" I0 U+ \2 i# r F' Z8 U- m/ K
}
" e6 \5 W( |/ G& r6 m3 ^. i3 j可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
8 A4 Q' a$ m# k/ b q9 @>> b = 1.1; c = 2.2;0 Y; J9 B P8 c9 q, F% ~
>> a = add(b, c)
1 C9 S! w, R( f/ M7 JmexFunction四个参数的意思为:
6 S. o. i: {7 F. Ynlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。4 Z. B% {" h9 M* E; t* u
nrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。( L; e% R6 ^* B+ d
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。! Y4 Y2 g4 _2 Z: n
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
2 |4 `/ z$ U% ?8 ?因为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类型的指针数组。/ r' U' I: a0 |3 o2 }; l; ~
完整的add.c如下:
4 d# \ m+ F6 K4 j$ E+ r// add.c6 m% u9 K8 N4 C A
#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数. L3 G9 {9 M# q' s5 H. g2 W
double add(double x, double y) {
! X7 g/ {/ z. R/ ? return x + y;% T+ H3 q2 Q0 q/ f
} // MEX文件接口函数
) I/ A' h5 F" G$ ^void mexFunction(
! B, E# x; A2 ` l. ^( I2 B int nlhs,
# ]8 ~+ i0 ^ g mxArray *plhs[],. o% S9 y. w9 N; O( c
int nrhs,
5 q0 q) u" Q1 T- x" K8 F const mxArray *prhs[]) {! G5 f" S5 S3 |5 Z2 m
double *a;
1 x: G% U0 x+ ~ double b, c;7 V% G9 [! O2 ^2 u2 H: g6 `
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);5 e/ z. u5 p0 H, ?) K( n7 n4 M" F
a = mxGetPr(plhs[0]);. `7 r+ F: w1 S5 p$ ?6 W
b = *(mxGetPr(prhs[0]));
8 f6 o& E2 N. n0 M; `8 ? X c = *(mxGetPr(prhs[1]));: Y8 c6 I% x: `# q
*a = add(b, c);. N" V; p' x8 S' c% j7 J
} `1 d# L% d9 v2 s! o2 x
mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:9 f# ]( M8 K# I1 F& b+ c
>> output = add(1.1, 2.2);" b' {/ J( Y# b/ B
在未涉及具体的计算时,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便是已计算好的结果了。# j% L7 G9 i% F" y1 W
上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。/ m' }0 l( ^) @, Z
实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保: _" S% j+ ~- Z8 D% s: n' r. `
输入正确。如在add函数的例子中,用户输入char array便是一种错误了。, G& q9 g; ~3 w9 k4 h1 Z# ?
从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。) H! B; E5 n$ Q3 W6 r
. G( V G1 X }3 y5 d$ ^
*********************************************************************************************************************************************
2 K0 J$ U' [& Y: g) x0 d# i. f/ r
6 K6 D' e0 l+ c( b# Q) _6 cmex 的目的,$ @6 [: e! ]! ?
8 b) f2 x( I: ~# U7 X% y
通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:
# }" _: B& [# v, {5 G# @& ^- ^# \7 |# J
1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.! J% o0 y; f& p5 q8 e
* q' ]! h( d) H- C2 k8 E t ?5 f
2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.# N4 z L& Z3 S p& _
+ `/ J! O% T/ z0 ?+ ^& N+ E; Q3、据称可以弥补Matlab硬件设备接口的薄弱环节.
6 z( W3 o+ b4 y1 Y! @1 C- |0 ^5 \/ r2 ~+ o/ V( i- `3 L& ~' Q: j
今天写了第一个使用MEX.
9 u8 c( e; [/ o6 X+ P" G# @8 k. R8 C6 w. Z* r
一个简单的对Matlab普通数值矩阵的操作.
% ~$ | Z: h2 K# d( S) V' _8 ]( ]( u# |0 Q, L. V( A
其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
/ Z4 {2 o( J# T6 t% \1 m1 t3 I
* r6 }: u5 K' O一律用int代替.
: u+ ~# r/ j) M: v9 I7 S- @( o5 B
#include "mex.h"& p0 f' ^) T) ~- _8 `
#include <iostream>. {* y6 g5 j3 m* j0 g
* @6 h) _! a5 Z! K9 Y0 o+ ~$ avoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])& i7 f2 w6 C* u
{
# I! T7 x$ o* B9 O% a! o$ @. e
( H; H" g) \7 c) v) V' aint i,j,k;, T% L* Y5 e. d0 m2 K& z
int index;
, r: p2 j3 v f! f" ^5 ?8 G7 M/ ydouble* pr=NULL;; \7 o. {7 U* D7 R4 N
double* pi=NULL;
9 \( v; c, j1 A3 h) f1 Aint M,N;3 Z `; s) a" k* E/ c6 t$ u6 e
int ndim;5 b. b- t& s+ `5 x( E, r
int dims[2];
& D6 q, g8 F6 O/ @( xfor (i=0;i<nrhs;i++)) L6 S: s5 ^; X4 O5 Z, b. u+ Z
{/ p5 D% Q; k6 R( J9 Y
if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2)) R/ f6 J3 M/ W3 T+ l$ D8 G- B" O
{
# f/ p7 c W( m/ }) o, F pr=mxGetPr(prhs);7 k6 [3 E6 [( o5 G; |, y _! X
pi=mxGetPi(prhs);; F( a; M1 Y, e: w
M=mxGetM(prhs);
( | _8 N, u/ y8 } N=mxGetN(prhs);6 E% e* j0 {1 Q! Z! Q
ndim=mxGetNumberOfDimensions(prhs);$ }+ [) f& T. X; _
, C5 J: u7 X) q; @( ]+ A1 S) k
mexPrintf("变量%d:\n",i);
, l/ ^2 s9 O9 \2 A5 L9 s for (j=0;j<M;j++)5 K8 a5 A8 [+ H3 t" q
{# o r5 s+ I# x O1 A
dims[0]=j;( {) `- U& N/ T3 Q( X, b
for (k=0;k<N;k++)
& S9 z) @' B$ G5 U$ d7 I+ z {$ t5 k5 b E. n' v! l8 N8 v
dims[1]=k;
1 f/ l0 W; U) f9 b# V0 ^ index=mxCalcSingleSubscript(prhs,ndim,dims);4 K- c. z4 Y3 F g/ @% S9 ~
if (pi==NULL)9 k3 H0 |9 C( T
{& k4 x, q- d4 Y) N. }8 j8 j( n
mexPrintf("%6.2f",pr[index]);
6 c; l h7 t: `- G& w }
5 z$ `6 \" L* @2 _+ H5 W( p else{
3 J* |9 H( n( d. G! T mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
" \$ }/ `0 _: U0 M' C }
+ m8 q. \& `3 F8 O }
! J A @* T) N( p& C% s mexPrintf("\n");3 q! D; J y9 n: c$ s1 S
$ Y7 c! X" z% f$ S* Q7 w }
9 X& H; `* A( t ! A3 K# }2 N |
}# ~- E) a4 M( o" u1 X
else{* G9 r( f7 X6 z
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);2 l1 N2 \! j5 @5 _' g8 M/ K# l1 n
}
) s5 z# C% J7 k
6 `. K5 M1 J# i9 }* `9 r( h
8 h1 K+ Z* U& q B% q}
: P4 H2 l6 ?# S# B( X- C9 s2 k( B9 ~) V F5 j+ u
}
; [# v( C* l- ?; P
) `0 _) \ v0 I9 X. ]# @Result:
! z& g- u! }2 Q4 d B$ E
. a. f* I# X3 G% Z' ~) ~6 V) {>>mex test.cpp
+ t( P: l3 \7 E- |5 Z9 l6 o# T& O>> test(a,b,c)3 P! u- O* M4 u8 o
变量0:
: h, q! r) d4 e, x' v) n( n0.35 0.62 0.83
5 r) R* U7 v+ j# X$ u0.20 0.47 0.59
# D( D1 V1 r: j8 x" o0 M6 H0.25 0.35 0.550 k& |: P4 \* A+ _2 o# i5 ~' z# J) S
变量1:
7 }* l$ j- L& _2 g, J. |0.92 0.38 0.53 0.57
. q$ C, ` M6 m7 M. d7 H5 G# @0.29 0.57 0.78 0.476 T p- m2 _" T- U
0.76 0.08 0.93 0.01/ M* p& M0 a% h; H9 y, X- y# l
0.75 0.05 0.13 0.343 e& w& @0 g% e3 M( T- C: p. Y
变量2:
1 J1 p3 J R0 ^; }0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
0 J' h& A. J% @/ \+ E6 W0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
* T5 K4 R: i) f* p* K" J3 K0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
" m* Q" J9 Z/ z: n6 e9 ~0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
9 U, {4 R# W4 H5 s% w/ p% y0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j& k% G3 O6 {3 D0 }. z
>> help test
# _+ ~( ]" E. }5 C/ }2 `/ k本程序用于调试mx______函数.$ l1 q# z F# w/ w1 @6 A" N
7 j6 d1 z, f/ G8 \
2 Y: a/ H& l4 T4 L& l4 \
本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html- g* I, O6 O+ h5 i
, ^% E5 Y6 i1 P0 R5 M下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
|
zan
-
总评分: 体力 + 5
查看全部评分
|