|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载)
. ?0 q9 w& |3 q( R9 I- `0 _+ _, v! p/ _( k# T' i e. Q
整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
3 L( j' i6 z! Q: H# X3 R
0 M, d' m) u# ?9 b1 T/ t4 f8 i一,设置操作系统的环境变量。. U: b( Z" ]* M- P
9 N2 `3 _& n# }* u6 \. w( A) M& c
系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
$ _0 A3 D0 J0 r- g: E( R. L& U0 b3 \9 t& }9 d
系统变量设置完毕后需要重新启动计算机方能生效。
8 E3 r- u! V: _( ~# p; D
' D% L2 K s- D2 F6 p/ g* M6 `二,设置matlab的编译环境) o- L+ B- F3 b
* H/ { W, ]. Q+ [# K- f' q
在matlab中输入命令mex -setup,选择Microsoft Visual C++ 2010
8 ?8 v) |+ [& a( T% t% J4 L: q- S3 v. J
再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010& z/ [& U7 |$ \- x& e x, ]' u, h
* B/ k8 k5 n8 E+ s `3 pp.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。3 |; ?! X @) R" x
% J6 S0 m e/ _. L Q. H
三,matlab编译.m文件: X( G8 z+ _% j F5 {
& `. x0 p( |* P/ G s9 c输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
/ Z0 h! _% X O- @
+ \- @% t8 c* n# \( j其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。+ ?: o8 c6 A% W. |
% B4 }: B$ O% Q- v: x2 V编译完成后得到了下图中的一些文件:
0 D% o2 }7 X: N7 W
! j: K8 j5 m. B
# [! l5 [% a! j# u' h; ]
+ M% _6 t4 J) O2 D& H& T. i* b
这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了)
8 a8 j5 ^) `+ r! ]3 c- E! Q0 g) `4 U, i+ U
四,VS2010 的配置 J. Z$ W z: F+ Z
+ {: j& O) ?% @新建一个控制台项目。/ Y& l* @* g1 H9 Z8 [* T% {+ T
$ v0 S6 G' j1 [5 e. O: O
打开项目的属性页,针对这个项目做如下的设置:- @7 ^, N3 N' U5 x1 r5 a' |
) j( u/ a. F, v; M, {' M, B
1.VC++目录下的包含目录添加4 [" @# k% R8 O, s2 p$ N+ k
: N# ^( W$ l& QD:\R2011a\extern\include(matlab安装目录下的路径). `" ?. G9 U6 ~
7 S2 M% t ]7 X# lD:\R2011a\extern\include\win32 (matlab安装目录下的路径,下同)
+ W' |' s* e4 y% V
3 V" v" s S& mC:\Users\lenovo\Desktop\aether\aether (你自己新建的项目中的路径,下同)
! p9 L" f! @% W% ]9 o9 c, Z; \' d: \! m! m. y
2.VC++目录下的库目录添加3 R+ x+ e) H- t) O. Y' h0 y! M: K
" O. P9 P* c2 P, r& [/ gD:\R2011a\bin\win32# i- f/ a1 W# v: @5 C5 W
1 G8 u5 Z# c& }2 [D:\R2011a\extern\lib
1 s2 w, J p' j- t& u8 o' F8 t" x* @9 L3 ?3 h' L0 g6 I3 H$ g) g! b
C:\Users\lenovo\Desktop\aether\aether7 y! i0 ?: M3 ?( e7 y
8 `0 O/ r$ |% g9 }; k# BD:\R2011a\extern\lib\win64\microsoft6 O& b( X1 I1 }3 I
( K- [/ @- d: \2 M4 e( ?% Y) J
D:\R2011a\extern\lib\win32\lcc! E1 j. q+ I1 X: [. @# q D
$ @- Y+ j" i3 d
D:\R2011a\extern\lib\win32\microsoft
+ ]" p; ]# _! s# u; c1 }* P$ n1 l0 G/ p7 t$ ^5 M. V, d
3.c/c++中的常规里面的附加包含目录添加2 a1 V; Y3 A8 ~( D) i
# j# n; Q" n% A1 A. W7 f+ H: j, e
D:\R2011a\extern\include
0 d6 y! c, S- M9 Q5 s, v9 O. r2 k& u
4.连接器下面的常规中的附加库目录添加! }$ b, {2 V5 _& j. L R
$ P0 U' {- i: R! C; o
D:\R2011a\extern\lib\win32\microsoft
: N: a/ c: p; o
/ b' s0 Y+ y2 `( p: A5.连接器下面的输入中的附加依赖项添加% j( K9 @6 D `9 u* v
5 Q0 \) k+ F0 Q9 V, T" y. f3 |libeng.lib4 ?. T' G) q! E C% |. F: w
( J% W' w7 k. I
libmat.lib
" f$ L1 P( b: U6 @' O3 J" ]2 ]1 Q5 y3 g
libmex.lib
. ~( n* d3 \5 Z, b$ a" W4 B u2 V" y! p7 e9 T" O
libmx.lib
2 z) [& j/ }5 l; j8 D0 ]5 K- E! w/ M3 z: M2 Q* m3 i3 Y+ f6 O
mclmcrrt.lib
6 B6 V+ {7 Y; D. R9 \- C, ]' F# z1 M: C( w2 |
mclmcr.lib
6 w+ [: t8 q- M- t5 z8 K: Y
7 H7 l, Q0 _/ C g! a$ saetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)
8 ]4 H' A6 {9 I5 Z
, S) U J% v9 T% R: L7 [在解决方案资源管理其中的头文件和资源文件中添加文件$ E1 |% \) u8 @# Z- G
, G1 c" x( u$ X7 d7 F, Y( ]1.在头文件中添加生成的.h文件: i- F1 g3 U3 |
0 b* o- L+ B" y4 X( E2.在资源文件中添加.lib,.dll文件6 `) H! t$ ^* q2 i4 U4 p+ k0 P
- K# a- Y/ |( G- F" w [) u3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。
7 C8 B- x0 I- f) e/ {8 |1 F9 A, ~8 d* D
(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C
5 A/ ^. v- V7 h
5 `, K+ V; U( C7 Y: i2 U, g) ~/ X$ @& r然后把.ctf文件也拷过去。)- f; |) T/ W3 h: V1 |5 [
9 F, u. U d" Q8 R4 C9 R- p
编写代码调用dll中的函数 u6 E, R' H: T# [; ^# c# n
+ }& p2 A9 x C- g& f8 k5 T
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。3 ^5 r6 m+ i9 z5 J1 S
! o& Z* x0 J4 j" g% s3 ]2 i& n
下面是一段主函数的编写样例:
8 b4 V% |* |( E X! F- \# q/ T4 \, l3 c3 f% P S9 c
// newdll.cpp : 定义控制台应用程序的入口点。3 e6 C& a, Y j
& e7 h7 ^: M6 s; Y/ |7 G5 L7 j//
$ A+ H2 e+ b- z5 c' r' `8 `
* w& F9 x, k/ \9 O* Q* O6 F#include "stdafx.h") d6 w% u8 L/ ~' C2 E* x
& t0 ]6 f( @, B9 D, n) ]
#include, o5 i4 y; T& Q' Y, `
' M9 J1 o# R3 C* Q3 W, u#include "engine.h"
2 W! t0 p8 o7 z @# k3 y' {' W7 w3 X8 q* t/ L
#include "mclmcr.h"
6 f& c h3 f$ o) E t$ q) A: [
& `' K- r: V! a4 r8 q+ d% r8 U#include "mclcppclass.h"2 B% p1 K. x% P- }* \
8 E1 b' @6 a: S% ?/ h
#include "libMyAdd.h"
$ T5 a# P. x) C; i: K, J' `1 ^& U% G3 d1 z: k! K9 W/ h
using namespace std;
# K+ {# n3 T) x$ P0 F8 a- |2 s% P- }9 V; d; N" b
int _tmain(int argc, _TCHAR* argv[])4 M# `& ]9 C# p6 K+ X
( L7 B7 p, I$ A9 M- j
{, S( I6 g* {: h) t! |& q% W6 K v
1 t% Q) X* Z8 z
if(!libMyAddInitialize())- f; {5 I! X" a4 s: T9 p
; ^1 H8 Q' g6 M* S! R/ q! W( J* S9 U {% Q# h! H1 m0 D9 Z1 l
6 \% r9 M- r# x1 r5 Q
//initilize failed!!!"<<std::endl;0 \7 t' M# D' A
' M7 q+ F; u6 d6 G' Y std::cout<<"错误..."<<std::endl;" H) _7 V& _) j4 V& i2 z
$ ^: d, C, n' m Y& P/ J- [ return -1;
6 K4 l# K8 q( i o" ]' }- b
: W! V/ s! g+ N* R* { u* |3 } }& }0 s; Y# `6 W
: K( q# q% W( q1 L) K double a = 6;! O- l7 C, {5 Y6 j9 [
% z: h! ~9 \/ S l$ U! B0 vdouble b = 9;4 }: q! R! z1 _: |2 |7 y
! x- x7 o T- J8 L- ^& ?, x7 p
double c;; {8 P T- k9 U1 Y
! J8 J. u% d# O* r$ cmwArray mwA(1, 1, mxDOUBLE_CLASS);
: X; V7 V, i$ n. H9 `' T h; U( \0 H1 q! d$ C
mwArray mwB(1, 1, mxDOUBLE_CLASS);0 }- u3 \) S( @
* V6 d P: Y: n8 ]
mwArray mwC(1, 1, mxDOUBLE_CLASS);
2 @3 }% O0 o4 B
, c" G1 [4 J* u- [: mmwA.SetData(&a, 1);: c1 F( Q# w# k5 q7 n
. g! K/ h. @7 o( p7 G* P7 r( R% kmwB.SetData(&b, 1);
- Y6 V- S9 t6 D* K5 v: m5 \, d% O$ I; {* ^/ i4 f
MyAdd(1, mwC, mwA, mwB);, v! [! I- U5 U
( C- }5 h# p- B8 V2 V( B* O. T
c = mwC.Get(1,1);
* e. C& \$ H2 m$ ~
' Y3 a; F- u- u/ |9 ~" s2 U3 Acout<<c<<endl;
* U/ \! Y2 c+ Q9 p1 H1 L+ P7 i* I0 S) n# u9 _
system("PAUSE");
& A7 U# {* {% X+ b
) b) n7 P7 S1 F% @ j2 ` return 0;. R" V3 ]5 E9 K
, j) h4 U! H1 f# p1 Q1 K! n
}
6 U+ V: ]: L4 J/ K. T6 k
5 {. `7 K5 Z" f& }这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。
, L. f! e& ? G6 \
) v, u% L, L$ S: Q) k$ |& j #include "engine.h"& Y" c! b# Y2 x# Y! Y* I
! I' Y2 {. e2 A- \ H
#include "mclmcr.h"
! {6 Y% T! _- z2 U: E
, F' B! D, B- g: D4 ]3 t! L#include "mclcppclass.h"3 F" d: s/ d- U: [4 j7 M
+ D/ {% H& q& `9 n+ ~2 N
#include "libMyAdd.h" 这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)
: S1 f: x- V4 J$ h
/ b. N- E0 d0 s3 F" S+ Y7 m现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。 出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck to you!0 R+ N: k' P7 M& [
: }; s+ n3 d5 v1 b6 O0 c
备注: v0 \( M$ V# [
; A8 M( I- w& Z: _- b1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。. ^8 j6 T5 B8 i7 n% C t
& Y+ A9 p$ m t) k
2.主函数代码中if(!libMyAddInitialize())是必须的。# O a8 A4 N, ]
( s$ R) T. U9 A& V3 e |
|