数学建模社区-数学中国
标题:
Matlab调用c程序
[打印本页]
作者:
梦溪517
时间:
2012-8-28 20:47
标题:
Matlab调用c程序
1 h9 j. D6 A) x4 P
Matlab
调用
c
程序
) k7 }9 _, d1 y' V: Q4 G( ^
文章来源:不详 作者:佚名
' {! f" l; K- q x& r, W
9 [3 L* K: \1 l g! Y# U
--------------------------------------------------------------------------------
! N5 u b: M& F1 \
4 o. J, e0 [& ^0 T3 d3 {
该文章讲述了
Matlab
调用
c
程序
.
# Q' L1 R; u: e! J5 v5 t% i# {
" G. z- g) Q' {
方法:
; {$ M5 c3 ^$ n I. @' \
第一步:要先在
matlab
中安装
c
程序编译器,步骤如下:
, C* o _$ \1 Y5 z1 M; @
键入命令:
mex -setup
;
% m9 L/ c) J$ t! R" N6 q$ c6 |
选择
c/c++
编译器;
% l& ]8 i" q9 k! }
选择
c/c++
编译器版本;
& l5 D2 m O6 P$ V8 t% V. D6 x' \
确认。
! ]. {+ R/ C1 y% T6 h
第二步:键入:
mex *.c
7 L2 s7 r; S# _( O
R( ^, `# `9 E( ]+ Q& W
*********************************************************************************************************************************************
) Q- ]& R3 D: z |* a
* y5 w: Z& w" w/ e7 S7 y
实例介绍:【转】
: a+ @# \" s9 U
: M9 ^' c; A! r9 o) |
如果我有一个用
C
语言写的函数,实现了一个功能,如一个简单的函数:
+ N, e* s* D t
double add(double x, double y) {
& A8 ~; n9 s# K1 _& F" F
return x + y;
: y3 H# ^: v0 O7 h
}
1 Y# u( [$ `+ _
现在我想要在
Matlab
中使用它,比如输入:
; N5 w" i, b; d& M
>> a = add(1.1, 2.2)
$ g9 H4 H& w4 g2 o1 n0 g# `
3.3000
8 i5 i4 n2 k' \, I6 z- a% t; O/ i
要得出以上的结果,那应该怎样做呢?
' l6 r" X5 R, J* H# S( c9 l$ r
解决方法之一是要通过使用
MEX
文件,
MEX
文件使得调用
C
函数和调用
Matlab
的内置函数一样方便。
MEX
文件是由原
C
代码加上
MEX
文件专用的接口函数后编译而成的。
8 C# r6 D) ~% a% w8 k( Z1 V) N9 ?+ f
可以这样理解,
MEX
文件实现了一种接口,它把在
Matlab
中调用函数时输入的自变量通过特定的接口调入了
C
函数,得出的结果再通过该接口调回
Matlab
。该特定接口的操作,包含在
mexFunction
这个函数中,由使用者具体设定。
/ [! i4 R( ]. {9 v4 ^. p2 H" T
所以现在我们要写一个包含
add
和
mexFunction
的
C
文件,
Matlab
调用函数,把函数中的自变量(如上例中的
1.1
和
2.2
)传给
mexFunction
的一个参数,
mexFunction
把该值传给
add
,把得出的结果传回给
mexFunction
的另一个参数,
Matlab
通过该参数来给出在
Matlab
语句中调用函数时的输出值(如上例中的
a
)。
6 k& {; l- G: H1 q4 s2 Y
比如该
C
文件已写好,名为
add.c
。那么在
Matlab
中,输入:
& h& l; Z' ?( k* I4 ^; U5 n
>> mex add.c
. S3 N7 n; c; H
就能把
add.c
编译为
MEX
文件(编译器的设置使用指令
mex -setup
),在
Windows
中,
MEX
文件类型为
mexw32
,即现在我们得出
add.mexw32
文件。现在,我们就可以像调用
M
函数那样调用
MEX
文件,如上面说到的例子。所以,通过
MEX
文件,使用
C
函数就和使用
M
函数是一样的了。
) z. N. r* }8 z( b: u5 b1 T& \
我们现在来说
mexFunction
怎样写。
* v# S5 J4 T8 e! B
mexFunction
的定义为:
' G+ n T2 A' t; a3 y7 Q/ Y5 Z
void mexFunction(
# p/ k1 C l: ]! `: P7 Y; p
int nlhs,
: x& j. U$ T( D) X: ~7 Y$ n
mxArray *plhs[],
0 H4 N! G+ ?, K- T$ R) I5 c( P
int nrhs,
6 w; F' [" X6 p0 o( ]
const mxArray *prhs[]) {
" ]; m3 |0 X! v& V+ o
1 o: B, O6 x+ T( L1 G9 a, P7 s
}
) c, @9 S) r+ \! u6 }9 Y3 U r2 v5 g+ a
可以看到,
mexFunction
是没返回值的,它不是通过返回值把结果传回
Matlab
的,而是通过对参数
plhs
的赋值。
mexFunction
的四个参数皆是说明
Matlab
调用
MEX
文件时的具体信息,如这样调用函数时:
+ A. V0 I1 {: h; w
>> b = 1.1; c = 2.2;
7 A! b& ?# f6 g# _3 p
>> a = add(b, c)
/ F* [/ X, g2 f
mexFunction
四个参数的意思为:
# U' I- D3 s0 i' Z. h# H
nlhs = 1
,说明调用语句左手面(
lhs
-
left hand side
)有一个变量,即
a
。
0 _9 R9 q( ]) i% W1 u
nrhs = 2
,说明调用语句右手面(
rhs
-
right hand side
)有两个自变量,即
b
和
c
。
( K3 X( n L1 y, G
plhs
是一个数组,其内容为指针,该指针指向数据类型
mxArray
。因为现在左手面只有一个变量,即该数组只有一个指针,
plhs[0]
指向的结果会赋值给
a
。
" A! Q5 E% R' L! _3 [' S% r
prhs
和
plhs
类似,因为右手面有两个自变量,即该数组有两个指针,
prhs[0]
指向了
b
,
prhs[1]
指向了
c
。要注意
prhs
是
const
的指针数组,即不能改变其指向内容。
9 m" B: ?+ ]0 l
因为
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
类型的指针数组。
' }+ y/ q, v% o/ N3 x1 e! I) K
完整的
add.c
如下:
& c1 F5 a( r2 ^
// add.c
# w. Q) Z! e" G7 |- o
#include "mex.h" //
使用
MEX
文件必须包含的头文件
//
执行具体工作的
C
函数
+ E3 D4 I: D* q, Q# r
double add(double x, double y) {
( u+ [* l8 j8 [
return x + y;
$ A$ V2 I/ Q+ ?
} // MEX
文件接口函数
8 u/ g# X( c) G/ w7 `4 F I0 ^
void mexFunction(
0 ^. z. s" l! Z! I
int nlhs,
! J& A6 y! V) q3 t
mxArray *plhs[],
) D7 c( P5 j {% j4 e5 N
int nrhs,
( W2 `" G, }( q, S8 l
const mxArray *prhs[]) {
9 o3 A( q/ @/ i; j0 f& y% Z
double *a;
9 g d. w+ J) \5 ? Z' u
double b, c;
7 H; ~ w8 l2 c1 j5 ?! [
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
; p; g& r" _' S" e1 u6 R
a = mxGetPr(plhs[0]);
7 g0 ~$ D" q, n$ E
b = *(mxGetPr(prhs[0]));
* `6 Z& L% G$ ]; i! G; I! c
c = *(mxGetPr(prhs[1]));
$ d9 j D1 u2 Q; h
*a = add(b, c);
! `" [9 J/ E" T0 Z" ?
}
* ]- L9 n" s0 Z
mexFunction
的内容是什么意思呢?我们知道,如果这样调用函数时:
; u; D% k& a% `9 m. B
>> output = add(1.1, 2.2);
$ X' f& Z, ~% `4 l
在未涉及具体的计算时,
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
便是已计算好的结果了。
+ I- n( l5 p( Y
上面说的一大堆指向这指向那,什么
mxArray
,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
* A- ^$ C7 e8 d. f
实际上
mexFunction
是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
- L3 F1 u0 p0 F& i5 s: ~
输入正确。如在
add
函数的例子中,用户输入
char array
便是一种错误了。
& {5 U& y4 Q+ G
从上面的讲述中我们总结出,
MEX
文件实现了一种接口,把
C
语言中的计算结果适当地返回给
Matlab
罢了。当我们已经有用
C
编写的大型程序时,大可不必在
Matlab
里重写,只写个接口,做成
MEX
文件就成了。另外,在
Matlab
程序中的部份计算瓶颈(如循环),可通过
MEX
文件用
C
语言实现,以提高计算速度。
' r [! B8 _) ?" u
. q8 X) E2 f; ? N, h( |
*********************************************************************************************************************************************
$ Q. j. s, L0 E! |) B% x8 {
1 u9 F& L0 R5 T% g
mex
的目的
,
$ h/ {# q1 W& ~* `) I5 Y
7 G8 Z+ [4 V1 D
通过
C/C++
语言编写代码
,
在
Matlab
中将其编译成
mex
文件主要可以做以下几方面的事情:
& \0 x0 T( ^/ E/ o' x8 r9 g
9 a& _8 R4 W6 H$ t# j( }7 }
1
、加快程序的执行速度
. Matlab
在
for
上如老牛拉车的速度确实让人抓狂
.
, E; X- d7 E/ N' s7 J7 T5 r( _6 Y
+ l9 M- Q# P- m( M7 y% k. f1 D
2
、将
Matlab
作为
C++
的开发调试环境
.
尤其是有大量数据需要处理时
,
用
Matlab
观察其中间结果十分方便
.
& ^& R; M) J& I5 |
0 M E' u4 d4 f: B& l
3
、据称可以弥补
Matlab
硬件设备接口的薄弱环节
.
3 B G: _ k. W8 Z: x
( X q& {& `( \, e1 q) F
今天写了第一个使用
MEX.
/ \( b) B* R+ c4 _4 U7 i
- V! `& X1 r/ T
一个简单的对
Matlab
普通数值矩阵的操作
.
$ A( u' v* V9 b% Q7 ^
: e$ y3 i2 |; ]3 V
其中
Matlab
规定的与操作系统版本有关的
mwSize,mwIndex, size_t
在
32
位系统上其实本质上就是
int,
所以
1 w( V* {% B" v2 r" L
* Y* x: q& {; \
一律用
int
代替
.
4 D4 G$ [5 r6 L( R: l* X
# r4 g2 {- I0 C7 z, w4 h
#include "mex.h"
0 \8 ^3 O% v" K" s1 b
#include <iostream>
& O! `+ i: f& P9 _0 S9 V G
]2 S9 F! Z7 f
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
% V# {2 V' o6 z& e/ r4 s" \: i0 g
{
) K: v' E& a) t+ n5 |, Y
5 c. t! r( q: V4 @3 z
int i,j,k;
3 x# p) X1 E K3 W
int index;
- J. C* w7 u6 S5 F/ e& l, o2 P
double* pr=NULL;
! f2 H5 }; r4 h
double* pi=NULL;
5 L2 A, p/ q6 M* c# L
int M,N;
+ B% G+ M- P. K6 x" _. g
int ndim;
* s: a# s: s) j) S5 T9 u- d' R
int dims[2];
" s7 m' ~: O) L% f5 Y" |. U5 G H5 ?+ \
for (i=0;i<nrhs;i++)
% C1 V* g0 e! |" b
{
( _4 Y) Y/ Z6 S. z: F
if ((mxIsDouble(prhs
))&&(mxGetNumberOfDimensions(prhs
)==2))
, E5 u+ L9 n+ w6 y. J' @
{
. L3 Q7 X: [, H5 h! \' }3 N
pr=mxGetPr(prhs
);
Z' M* }1 y1 o
pi=mxGetPi(prhs
);
" _5 ~( P$ ]5 I% Q" |$ Q
M=mxGetM(prhs
);
- L" a6 P; `4 H* R3 N
N=mxGetN(prhs
);
0 y' k7 q3 y' z2 J; H
ndim=mxGetNumberOfDimensions(prhs
);
3 X' J% U6 l, `4 J
! J; }% D, @- \: O/ ?
mexPrintf("
变量
%d:\n",i);
4 n7 X( O0 T3 w. h; J3 A
for (j=0;j<M;j++)
) H$ x1 U8 `! e! B5 C/ D
{
* h+ q3 L2 V+ ]
dims[0]=j;
) ]+ |; B7 ], C! K* h
for (k=0;k<N;k++)
/ ^4 \% P' }) l
{
, f" s2 h* @/ k; S# O+ d
dims[1]=k;
. z2 [9 M# @0 }7 ^* o0 k
index=mxCalcSingleSubscript(prhs
,ndim,dims);
: i, o# z% n& M* S3 q% c7 l
if (pi==NULL)
1 Z' {7 F& @% {4 ~; j4 {# {* r
{
6 e! |5 n L D5 Y ?3 v c
mexPrintf("%6.2f",pr[index]);
0 N9 G9 k4 L+ G# o% V% S+ b9 U
}
& R& k6 B; n8 ^$ z- G/ X7 S
else{
+ B- L9 b& ~) E( i
mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
- k3 }, v% ?% g; B% e
}
! g0 E# A& J( r c) Q( y
}
0 X( | l5 M; X& d% m
mexPrintf("\n");
) D) I7 w9 V0 M8 |7 ]8 |+ T6 j
. G. X5 `6 [9 @1 ~9 C5 l( o
}
2 c4 M5 J# O$ k. n3 w
* U0 ^$ p5 p& ^- ?1 E y
}
3 f. q5 {* e% _
else{
* D( v% M% H2 Z8 ^& h
mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
! U+ f5 P8 e" v* u9 j
}
8 F0 G$ k4 B7 ^0 f* z! I- M
, D3 M, ?" |9 e$ p* k* T
* [6 A/ }9 d0 ?* ~: `) O' \$ \
}
' s, k) Z2 z. C. R0 n6 ]
! e$ t/ A7 h& \) ~1 @* k& B8 I
}
3 W: K! I7 s5 g/ z$ o
/ @8 k* P% S T# j. E4 i
Result:
2 Y6 w4 p4 l, L& f/ {, j# s
+ b I4 r6 r: a. q- j- p8 d
>>mex test.cpp
3 g; G* K2 }8 N0 V" ]
>> test(a,b,c)
: |9 i3 S$ ]/ }5 H' L8 W
变量
0:
6 q U$ U2 c( |9 B; a
0.35 0.62 0.83
# R3 o7 p$ A3 ~, i+ ~: m: d! y
0.20 0.47 0.59
8 m1 F1 W/ B6 M3 e+ z4 q% R' W
0.25 0.35 0.55
) T. _& }; H8 J" v9 ]
变量
1:
, ~% W6 q1 [! z5 K6 ?3 n7 L7 S
0.92 0.38 0.53 0.57
7 j) t* X" l( V# q$ c. R5 u, Q. I6 z
0.29 0.57 0.78 0.47
/ R! Z' L6 \ A3 g+ C. g
0.76 0.08 0.93 0.01
5 ` E: S3 Q0 u/ B, E& V
0.75 0.05 0.13 0.34
) f1 c0 S2 s5 O- E
变量
2:
1 ?4 B% K( J, d! Z& l/ V
0.16+ 0.87j 0.60+ 0.43j 0.45+ 0.14j 0.83+ 0.85j 0.11+ 0.08j
. G H2 Z9 {! O6 t9 O: z
0.79+ 0.08j 0.26+ 0.91j 0.08+ 0.87j 0.54+ 0.62j 0.96+ 0.24j
- I$ }2 V' W; P9 M- ^) q
0.31+ 0.40j 0.65+ 0.18j 0.23+ 0.58j 1.00+ 0.35j 0.00+ 0.12j
8 Y' Y. t7 ^" g D: q
0.53+ 0.26j 0.69+ 0.26j 0.91+ 0.55j 0.08+ 0.51j 0.77+ 0.18j
% [6 i: x: b" {
0.17+ 0.80j 0.75+ 0.15j 0.15+ 0.14j 0.44+ 0.40j 0.82+ 0.24j
) C6 l0 N2 }! J. ?# O" W; m; c0 q6 R
>> help test
8 ~% p& C" x+ t) i+ q; t
本程序用于调试
mx______
函数
.
" t# x' y4 R% x& a1 J
- Y: Y1 V; r7 F) t. f
/ h T) v9 i: B, \
本文来自
:
高校自动化网
(
Www.zdh1909.com
)
详细出处参考
(
转载请保留本链接
)
:
http://www.zdh1909.com/html/matlab/14744.html
8 G* n/ x3 m# y1 j! I
. H% [/ \: z9 q' r( ~& a' t) ~ }
下面是其附件,内容一样,方便下载
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