数学建模社区-数学中国
标题:
Matlab调用c程序
[打印本页]
作者:
梦溪517
时间:
2012-8-28 20:47
标题:
Matlab调用c程序
/ ?' J/ x8 h8 g+ i8 A+ J# X
Matlab
调用
c
程序
9 E! w5 G0 H/ `# e+ y7 T& [: R
文章来源:不详 作者:佚名
! m; _2 R2 P+ k$ o' o
. ]/ D# I }) S6 l; X1 K: `7 b
--------------------------------------------------------------------------------
/ ]+ z( f% b9 Z0 S, m
. A1 b( l( C6 b9 B/ D1 V
该文章讲述了
Matlab
调用
c
程序
.
* h% G5 A* V. t: v. s/ z
4 S9 a3 @! T6 i4 k: b
方法:
+ v. }+ u: [; l
第一步:要先在
matlab
中安装
c
程序编译器,步骤如下:
% t( h2 [2 Z# L) h$ D) P
键入命令:
mex -setup
;
# V2 Y$ }( A: D( K5 I( @
选择
c/c++
编译器;
# q. ]" ^3 G/ `9 ]# V3 d
选择
c/c++
编译器版本;
: S/ i! M2 {# }/ f
确认。
5 Q3 |( S7 T9 y. l
第二步:键入:
mex *.c
/ B8 J) }7 t& Q" N& q& B
. [! _9 U/ C& Q- F; j' C
*********************************************************************************************************************************************
% U+ a! {: I# g/ s3 T! r2 A( ^; g
6 W* T, x4 j) D& b7 c
实例介绍:【转】
8 O7 x5 Z* A* q- g2 y/ `
# @ C8 m+ X _1 H& W) A
如果我有一个用
C
语言写的函数,实现了一个功能,如一个简单的函数:
6 y& d' Z/ O/ S+ G, h
double add(double x, double y) {
$ v* C9 S* t& p3 s7 v3 Y
return x + y;
) Q8 l/ l/ N0 f
}
' |/ S5 v9 i A7 m. L* Y
现在我想要在
Matlab
中使用它,比如输入:
2 o) n$ W7 n, r0 R7 O, t' C1 b6 ]
>> a = add(1.1, 2.2)
3 [ H3 M( v' U
3.3000
& Q' W2 C' v! t
要得出以上的结果,那应该怎样做呢?
d5 k1 H/ l7 ]3 B
解决方法之一是要通过使用
MEX
文件,
MEX
文件使得调用
C
函数和调用
Matlab
的内置函数一样方便。
MEX
文件是由原
C
代码加上
MEX
文件专用的接口函数后编译而成的。
7 B4 P/ |8 m2 }1 e7 n" }- r
可以这样理解,
MEX
文件实现了一种接口,它把在
Matlab
中调用函数时输入的自变量通过特定的接口调入了
C
函数,得出的结果再通过该接口调回
Matlab
。该特定接口的操作,包含在
mexFunction
这个函数中,由使用者具体设定。
1 t8 L/ _) r8 b9 W- a
所以现在我们要写一个包含
add
和
mexFunction
的
C
文件,
Matlab
调用函数,把函数中的自变量(如上例中的
1.1
和
2.2
)传给
mexFunction
的一个参数,
mexFunction
把该值传给
add
,把得出的结果传回给
mexFunction
的另一个参数,
Matlab
通过该参数来给出在
Matlab
语句中调用函数时的输出值(如上例中的
a
)。
, b0 k4 e+ |: q* k
比如该
C
文件已写好,名为
add.c
。那么在
Matlab
中,输入:
: [: X1 V+ h9 m: P( n" W! t
>> mex add.c
7 L9 H3 g4 u9 N6 R
就能把
add.c
编译为
MEX
文件(编译器的设置使用指令
mex -setup
),在
Windows
中,
MEX
文件类型为
mexw32
,即现在我们得出
add.mexw32
文件。现在,我们就可以像调用
M
函数那样调用
MEX
文件,如上面说到的例子。所以,通过
MEX
文件,使用
C
函数就和使用
M
函数是一样的了。
8 I+ a0 ?3 Z2 x; `. C8 j
我们现在来说
mexFunction
怎样写。
- q7 p* ^8 P$ }- w# k
mexFunction
的定义为:
$ W9 Z1 x5 [2 t- e8 `( \3 q8 v
void mexFunction(
+ [. F2 |3 E# |0 T* `9 F$ {* @" C
int nlhs,
$ R m0 j9 K6 O& ?
mxArray *plhs[],
9 Z) U7 T8 i& K; ~' l3 B2 ?8 c+ l2 i
int nrhs,
& r- Z" k3 B( k, t9 G, S
const mxArray *prhs[]) {
W% o6 Y4 Q. k* r* G4 o- k- U
3 u3 H/ C# l! Z/ \
}
* a+ V* _, ?& ^' K$ [
可以看到,
mexFunction
是没返回值的,它不是通过返回值把结果传回
Matlab
的,而是通过对参数
plhs
的赋值。
mexFunction
的四个参数皆是说明
Matlab
调用
MEX
文件时的具体信息,如这样调用函数时:
. @4 Q$ U* m$ O6 s/ x; y8 h# F, I
>> b = 1.1; c = 2.2;
( @. F2 J" b, V( ~4 r
>> a = add(b, c)
' G5 H9 h# ^* I2 r- o; i' ^
mexFunction
四个参数的意思为:
3 X: `5 g V; W; K. m2 j
nlhs = 1
,说明调用语句左手面(
lhs
-
left hand side
)有一个变量,即
a
。
7 }4 v) Z3 @( F& ~5 I! ]) z
nrhs = 2
,说明调用语句右手面(
rhs
-
right hand side
)有两个自变量,即
b
和
c
。
" P0 e% O% l$ ^! H% j0 I& H
plhs
是一个数组,其内容为指针,该指针指向数据类型
mxArray
。因为现在左手面只有一个变量,即该数组只有一个指针,
plhs[0]
指向的结果会赋值给
a
。
4 ^8 R% s. q$ |; f+ @
prhs
和
plhs
类似,因为右手面有两个自变量,即该数组有两个指针,
prhs[0]
指向了
b
,
prhs[1]
指向了
c
。要注意
prhs
是
const
的指针数组,即不能改变其指向内容。
" r; v5 k) T; b- f! q5 x
因为
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
类型的指针数组。
& |! T1 p3 E M+ V9 \# `
完整的
add.c
如下:
; Q7 {0 B; E- O- p8 ]
// add.c
" r! z7 W9 x4 X# y
#include "mex.h" //
使用
MEX
文件必须包含的头文件
//
执行具体工作的
C
函数
n1 \( n7 L9 r0 H: {8 M \
double add(double x, double y) {
9 ^: }7 r% D2 c% F- ~
return x + y;
% }6 Z% b5 a' i/ k
} // MEX
文件接口函数
. U6 X, [' K' y- ]! N4 X @8 J
void mexFunction(
/ @1 J1 x2 p7 K
int nlhs,
6 p* K" \- K' H/ r% I* ~: v! X1 }2 i
mxArray *plhs[],
Y" N/ I; k& U. H7 K0 z& b. B: ~
int nrhs,
2 I( z& B3 `/ w% E7 O% T3 ~
const mxArray *prhs[]) {
5 D# D# R1 P2 L+ D
double *a;
& Z% X8 b8 R) i: K9 U
double b, c;
* l8 D, T' B0 H
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
6 O$ _( b7 g& ~
a = mxGetPr(plhs[0]);
) w W2 D: f& x5 G
b = *(mxGetPr(prhs[0]));
' ~# C$ w$ W8 C+ d, i/ S
c = *(mxGetPr(prhs[1]));
" P3 \& a# U1 ]4 Z( u
*a = add(b, c);
$ i6 ?' g* ?; v- G. V4 f
}
- y3 r. N4 Q8 b8 Y0 L
mexFunction
的内容是什么意思呢?我们知道,如果这样调用函数时:
6 s8 w6 M% e# C" |" b2 T* _
>> output = add(1.1, 2.2);
/ t2 i$ z( |; v! R* p4 `
在未涉及具体的计算时,
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
便是已计算好的结果了。
, l3 W( e( o8 h2 R. q8 l- D
上面说的一大堆指向这指向那,什么
mxArray
,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
|9 \5 O5 l `- ?5 F( e9 t& m
实际上
mexFunction
是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
m1 A+ A% z' ]
输入正确。如在
add
函数的例子中,用户输入
char array
便是一种错误了。
: B0 X: K# J4 \$ A% R
从上面的讲述中我们总结出,
MEX
文件实现了一种接口,把
C
语言中的计算结果适当地返回给
Matlab
罢了。当我们已经有用
C
编写的大型程序时,大可不必在
Matlab
里重写,只写个接口,做成
MEX
文件就成了。另外,在
Matlab
程序中的部份计算瓶颈(如循环),可通过
MEX
文件用
C
语言实现,以提高计算速度。
% ^6 P2 Z: S+ Z
! E# g3 J1 a0 T4 Y" P8 m S' T
*********************************************************************************************************************************************
- K- [8 k7 W7 Z5 x/ ~7 s
1 b( J4 H, V; M! H
mex
的目的
,
/ Q1 ~+ O+ M; o9 |( B/ j' w
$ l3 b% ~1 _6 ~
通过
C/C++
语言编写代码
,
在
Matlab
中将其编译成
mex
文件主要可以做以下几方面的事情:
. k8 v/ P0 A) K" m7 w+ k3 M
a0 p m% \1 a9 a% J3 G
1
、加快程序的执行速度
. Matlab
在
for
上如老牛拉车的速度确实让人抓狂
.
* l1 D; p/ I: x5 z9 G
; G7 O& A. f) t1 i
2
、将
Matlab
作为
C++
的开发调试环境
.
尤其是有大量数据需要处理时
,
用
Matlab
观察其中间结果十分方便
.
, f; t) J4 j, L7 C4 h
) X$ E9 k- y+ s% \
3
、据称可以弥补
Matlab
硬件设备接口的薄弱环节
.
& [8 J& E2 s7 S$ d
! f" `' A1 O5 Q0 p$ ~* x
今天写了第一个使用
MEX.
( A% Q5 l% p( H
1 Z5 B% v# t7 d; p3 z) t- n' K" t
一个简单的对
Matlab
普通数值矩阵的操作
.
% W8 J Q* i8 n: l0 g
- g! g9 H. e* n9 \
其中
Matlab
规定的与操作系统版本有关的
mwSize,mwIndex, size_t
在
32
位系统上其实本质上就是
int,
所以
/ O$ ]9 ]( P) Z' j, t4 b8 z# r
+ i; e/ @! ~9 P! `. P& V
一律用
int
代替
.
U) Z, F! B) j
o3 P% z8 d- j# b: [) y/ z
#include "mex.h"
. y! d: y$ E6 Q5 M) K& b! P
#include <iostream>
; [% t, A9 L7 }
) e; y9 p; B1 `. H
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
: g) j8 _) K1 n* O1 {& @6 y
{
7 c2 U8 S/ q' x% m
7 x: H' J% b( i- q
int i,j,k;
# p6 W- n9 }8 E2 G7 M; }
int index;
4 x$ O$ X" x7 S8 N6 P" S+ f P$ K
double* pr=NULL;
+ [ M2 @" _* M$ _* ?/ o
double* pi=NULL;
2 X# ?8 \0 y3 \% }/ E
int M,N;
" E4 ~- H# q8 w" W3 P4 f2 q
int ndim;
! L: a. q, V# g+ A2 K
int dims[2];
2 Y) i6 @- ^3 x6 V* x1 [+ T) n
for (i=0;i<nrhs;i++)
* F) F1 h2 f- x1 R6 U" L1 N% J0 D
{
% z5 ?6 d9 Y" a/ j
if ((mxIsDouble(prhs
))&&(mxGetNumberOfDimensions(prhs
)==2))
, d1 ~8 t" C( e9 [3 A- T
{
@8 y# h# k+ {) j. q* i
pr=mxGetPr(prhs
);
0 L% A) S3 t7 N N9 @
pi=mxGetPi(prhs
);
7 L( k* q3 |- |6 k: C5 Q# w8 A
M=mxGetM(prhs
);
$ L% V9 |: G4 T7 P; f. y5 T6 K8 N
N=mxGetN(prhs
);
" E( O Y! c. k! B4 | U
ndim=mxGetNumberOfDimensions(prhs
);
3 B# R$ e5 I9 F
: I" U! a" i7 _2 T0 j
mexPrintf("
变量
%d:\n",i);
" f. D4 q$ Z) a. o8 Y
for (j=0;j<M;j++)
+ n$ d. k$ ^; o
{
9 i, E8 u9 I( V& t5 g3 Z
dims[0]=j;
4 X: d) l6 ~: v1 m' B. o* N
for (k=0;k<N;k++)
! m& ^ h+ ]* k5 H
{
* y1 z8 b" i: Z' z1 M
dims[1]=k;
! y& G& d: @+ |5 k2 X @
index=mxCalcSingleSubscript(prhs
,ndim,dims);
a# G$ k/ ?9 T3 c, h3 {
if (pi==NULL)
; C, O+ ~! P) L! y5 k
{
0 d/ Z! G! o! `/ S& ~. E t$ i' [
mexPrintf("%6.2f",pr[index]);
1 }. q- H+ }/ ]4 t! ]7 q* W8 q# F
}
( t+ J- |+ x& P; j R' k; U) ~. {5 q
else{
; @% B1 l& P8 w' E/ s0 I
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
) J* p' a* \9 N: T8 B8 y }% F I8 e
}
! Q5 {' F+ _% \9 E7 A0 L
}
; M% u- K- A5 X4 a
mexPrintf("\n");
1 t& q7 }! ~2 v6 V2 P n) _/ }
r3 @! e+ N1 ]
}
! T. N1 N3 Y* v+ ]
# C" T( V" `5 K
}
- W4 c7 B$ O; Z0 \7 }3 h `
else{
) _1 P# h! z3 |/ p, I- }0 Z
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
/ z+ o+ ^- V; `: L
}
9 m. j7 ?5 D0 V: I N. M6 W
@6 s/ _) \; r3 B) W
& R2 j/ b1 |' ~( M7 N
}
, i0 e6 N+ W3 o9 v& Q2 i$ g% P
: u8 \2 S; Z0 @ {5 u
}
9 K2 h& `4 e N5 W8 v0 d" v
5 v5 i o. c$ r/ l0 }
Result:
9 u$ a ]* X9 f4 z3 w. w z( I0 s
1 l0 i% k. h- }9 {
>>mex test.cpp
) J( O# y8 i) ?8 ?
>> test(a,b,c)
. L% e. a( D5 E7 G
变量
0:
6 x# ^* g8 v& d7 e: R {0 e
0.35 0.62 0.83
( \, l) a3 G" e I2 x: G! l* k! G* F" W
0.20 0.47 0.59
h! S- e6 X4 D
0.25 0.35 0.55
1 Y A: r* P) h4 _. c
变量
1:
. r( W+ e; R0 o- a, l# N) F
0.92 0.38 0.53 0.57
! c _( N) L$ K
0.29 0.57 0.78 0.47
% l: Q5 G5 w- C
0.76 0.08 0.93 0.01
& [ D; Q0 k+ ]5 _) d9 }0 d- P0 k
0.75 0.05 0.13 0.34
! @, r% }$ Q9 S5 G! b
变量
2:
* h% {8 E- b+ E* f% G* i
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
; Y1 D, s4 N6 \
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
) g9 m7 d8 ~) o. M. ]$ n% b
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
/ h! I) E( U1 R. M, a& W& w, M5 e
0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
' _9 p# O' s+ r5 B0 j; F6 @1 z" {
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
' a& r: F+ v# I) H+ W
>> help test
, z0 ^- r$ V. V* E3 p- o P; u
本程序用于调试
mx______
函数
.
! o* A# |+ g% d( o
! _1 p* K9 G4 a5 Y3 j, M1 `/ O
' \1 Z4 L9 K, ` v) V1 _4 G' g
本文来自
:
高校自动化网
(
Www.zdh1909.com
)
详细出处参考
(
转载请保留本链接
)
:
http://www.zdh1909.com/html/matlab/14744.html
3 l7 O* `3 k' V1 z. @
0 R5 g. I/ F% ?$ y$ S9 X# V
下面是其附件,内容一样,方便下载
Matlab调用c程序.doc
(41.5 KB, 下载次数: 10)
2012-8-28 20:47 上传
点击文件名下载附件
下载积分: 体力 -2 点
作者:
天海星云
时间:
2012-9-1 21:44
很不错的资源
作者:
wangtianyang
时间:
2012-9-3 09:25
嗯嗯,很好谢谢楼主
作者:
gucci_purple
时间:
2013-1-3 11:17
顶一下。谢谢楼主啊~~
作者:
tequila33
时间:
2013-1-8 21:11
很实用啊....谢谢楼主~
作者:
lieove
时间:
2013-1-14 23:11
为什么不直接用matlab的m文件写成一个函数得了啊!!!何必这样麻烦呢?
作者:
zzllnnhh007
时间:
2013-1-27 19:04
谢谢数学中国的老师们,老师辛苦了
作者:
墨羽飞
时间:
2013-3-1 17:45
谢谢楼主~~~~~~~
作者:
fjnanyuan
时间:
2013-4-5 12:25
好高级啊,为什么要10个字符啊
作者:
jonejack11
时间:
2013-6-4 00:38
正是我想要了解的,其实编程是相通的,关键是怎么编
作者:
pcyaoqiang
时间:
2013-7-12 16:01
支持一下啊!!
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5