|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载)
+ O+ e2 y% g! m, e& m# h/ y! \& _9 U4 l" g/ Z+ ~1 ^! T) p l' @
整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
* g# v, l2 _' Z3 v: D
6 w" o5 s$ Z! a1 l$ v5 u一,设置操作系统的环境变量。2 T7 k9 @9 O; e
. x7 q' R% t) c! y7 y系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
( |5 T2 } B& \9 c$ z' E% M5 I1 p/ O9 x0 D0 P5 H0 [6 B$ ]$ |1 ^
系统变量设置完毕后需要重新启动计算机方能生效。
2 o/ W7 |4 p4 \$ u4 z% |- e
% \! X3 n" }% y0 J8 u9 r二,设置matlab的编译环境 @0 X) G+ p/ O- }* Q8 j9 X9 f: q
- Q9 K6 S; U& K$ ~" f在matlab中输入命令mex -setup,选择Microsoft Visual C++ 2010( {) @( b: q/ z+ j8 C
6 f$ s' D" e! g1 n% K$ d再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010
* m" y2 Z, U, r' ^4 J7 ? i1 G1 w' G2 m& X
p.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。% l8 x* d& o( }) n3 v; i9 x. f- W& T3 R J
9 ?$ D4 Y8 B& _/ m/ d9 k
三,matlab编译.m文件3 ~, _& Y9 {$ ?" H. d; b9 g( I, d
9 f1 f; M- G7 D) d$ V/ @6 @$ G
输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m6 p$ J: f( b( i7 ~$ x
9 `) [7 h% N: u y$ x& S% c w. A; `
其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。( ]* ?( u% V Y$ \; b. d
, M2 |7 h" S2 a编译完成后得到了下图中的一些文件:6 e. V0 T4 }7 v# _: C8 {* X+ C A8 X7 u
: I: O: X7 t0 _' Z; Q; Z: q$ t- X
7 J5 ?8 w. w, G# E" [+ \9 Y6 k, ]2 _) A5 F- L1 x
这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了)( u' ?+ U+ L# {# ^ P
& j" }. P% c$ i8 W8 n四,VS2010 的配置
/ P( E5 E2 S" X6 f! j0 s: s8 O. q/ K- ~2 L* y* x1 v
新建一个控制台项目。
* `9 u6 h) Q1 E7 Q+ C7 N0 T5 E* g% {& Z" t
打开项目的属性页,针对这个项目做如下的设置:$ J$ o9 _5 i4 ~3 k; M( N
$ F. @: H0 l; l$ o+ E0 o; g1.VC++目录下的包含目录添加/ J6 M5 s: J' j+ K& y/ q, z1 i
! @7 V4 i1 P8 c4 f3 o
D:\R2011a\extern\include(matlab安装目录下的路径)
, B2 ?( ^6 f! X4 ^/ m2 f. R2 E2 \% r8 B* {/ e5 y' L2 B% @/ V
D:\R2011a\extern\include\win32 (matlab安装目录下的路径,下同)
& k( e" ?5 A$ N4 u7 |5 M$ _/ N$ Y* Z0 d$ s
C:\Users\lenovo\Desktop\aether\aether (你自己新建的项目中的路径,下同)# C+ L2 @/ e- d
1 z1 s+ l+ }6 V7 p
2.VC++目录下的库目录添加
8 c8 v% \- b t! A6 o$ J) r" T8 c2 V' _4 _3 |
D:\R2011a\bin\win32$ I- ?) ~* w P# o9 L2 d' r: `5 \+ a
1 ^5 Q6 ~3 q/ F6 xD:\R2011a\extern\lib, y9 X, ~( U- @ g6 }/ I! }
# v( y+ Z% a' l* h9 L
C:\Users\lenovo\Desktop\aether\aether, ^7 b3 \$ Y3 J2 ]
8 F) @' y0 |5 o% _ o
D:\R2011a\extern\lib\win64\microsoft
+ i& U9 L8 p) T1 I+ J j4 U% [# u6 T' k* ~) P7 I
D:\R2011a\extern\lib\win32\lcc
3 ?) {$ h, H/ `7 n6 U& S4 _; C p/ T, Q8 c0 M( k: S
D:\R2011a\extern\lib\win32\microsoft+ B. ~2 a7 x. `+ D* D! p
2 o* t: f, T/ {5 Q% q6 H3.c/c++中的常规里面的附加包含目录添加0 r4 v9 N$ n" y9 Y2 k: h
7 [" x+ V M5 W& gD:\R2011a\extern\include
* g; v* u U3 L
/ x' k) Q; Z- p8 }/ H8 H) g4.连接器下面的常规中的附加库目录添加3 e* o/ R% Q% |4 U' X# P& f- F' }0 K, z
/ ~' y8 n6 c# w& V K
D:\R2011a\extern\lib\win32\microsoft0 j" ^3 ~1 y4 i2 [4 f, ]
4 Z) n; z+ `* l9 j9 A$ @5.连接器下面的输入中的附加依赖项添加
+ x/ g" P$ P. O: X
: }2 b8 |4 N* R) O2 {; p* Ulibeng.lib
" C, W8 q) T, d5 k5 L
: O" X8 ^) d1 D( w$ A* C7 [libmat.lib6 K6 B9 N7 [" W5 `
4 L; U8 G4 Z8 {3 l" G6 ^libmex.lib: k" s# y6 } H {1 c" h7 T2 d
# Y' O2 Y( _# E" _
libmx.lib ^5 _* K2 E1 v, }3 J3 p# ?
/ S( O' O U a7 I0 U" q$ |0 hmclmcrrt.lib) i1 G$ T; M8 }! Z
0 \4 y7 B% V- f9 V. ?1 N
mclmcr.lib
" r7 `6 J0 o: }0 d# U& g/ V& z
aetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)
+ I# h2 v. s* L) F4 s# x% Y, ~# W1 X/ U$ B
在解决方案资源管理其中的头文件和资源文件中添加文件% Q0 b/ q: c8 J0 q3 l
9 U7 v! [6 J4 h1 o1.在头文件中添加生成的.h文件
0 v& w6 c2 b t
% O% P; P. W2 g, |2.在资源文件中添加.lib,.dll文件% ~/ p( o7 \( J) C
( v+ Z0 e- p! X( E$ N9 M6 E3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。
% |8 `3 _2 A) H# R7 [2 u/ _! x9 S# n( q3 \! ?& ]
(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C& R% j- f, S0 r4 M+ ]4 n& z% s
, B5 h2 h7 ?8 ?1 g1 n' a5 _然后把.ctf文件也拷过去。)
8 W7 ?2 m! o% c3 w0 v# w- ]4 M" ~' V4 w% W8 Y* R
编写代码调用dll中的函数
! j: w0 @+ T/ i6 M X0 L3 I0 m" Q7 A* g% o) V
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。
+ J( q; O2 f( J3 C3 ?' c3 ^/ A7 I9 g* ]" T" W
下面是一段主函数的编写样例:2 r$ ]! I" U9 u3 |( s6 D
3 {% J. D3 ?5 d P6 `& m! j/ F5 V
// newdll.cpp : 定义控制台应用程序的入口点。
7 R# b. Y! v# r+ z2 j$ G; j
+ r2 p- ]" j' x9 ?+ _//
) U& {& _& I% L4 L% A
1 I5 u F! O' ?% F9 t0 d% P#include "stdafx.h"1 b3 B6 w: a" S% ?
1 h4 m, D2 K+ P#include
- d4 e! \/ `/ U8 H0 G* Z0 }+ V4 t3 _6 W" D. G# `% n2 m
#include "engine.h"
+ F0 E6 i0 [& M# [+ q! Y. @ ]9 W2 c+ a' A( a$ u1 {4 [, Q
#include "mclmcr.h"
P$ r2 ~8 w$ v3 V. R; s; ^2 w, P
) I: _- c6 x8 x: r7 ^6 s/ t#include "mclcppclass.h"
9 s; H5 Q9 Z+ Y: ~# R) J/ |! k6 |7 r, M8 K! O
#include "libMyAdd.h"
- o* X9 @$ w8 z- l/ X8 h4 W- ?9 V1 N( P. B7 y
using namespace std;! Q# b; \: t- G) Y
: z' n8 `2 w% J) Vint _tmain(int argc, _TCHAR* argv[])
# |1 U8 g# g9 Y6 G) b) Y: W4 [9 i6 i6 B0 D) `+ |! b
{
' h) q9 @5 ]% [) U7 E) ^9 A5 s, z, p3 [7 z9 [" n) J# ]! Y9 a
if(!libMyAddInitialize()); |: s2 ?2 u# Y8 W# l1 |7 H
& W. h0 u# S/ n y+ P2 z$ i
{$ B7 t2 ^9 ^9 w, C9 s
* F& ~) K( n& Z: ?, Q% m# y3 c //initilize failed!!!"<<std::endl;
7 N1 O0 j. @% }& N9 \) H; O; Q7 r+ B0 n$ `! _6 l; }" ~
std::cout<<"错误..."<<std::endl;
) ^! b; X) T6 J9 I' F' q, o" J" Q! j7 y3 V% \2 P
return -1;
2 p5 [, P" W$ g& E" u: T" V; c3 z1 \/ }) D( m/ X3 @
}
7 T/ }' d W- b) Z' t
7 ^% P% E$ W9 r% Q' t8 c1 v1 o double a = 6;7 k( C9 ?' j6 f, q. ~ B/ x
1 M1 q8 C9 e8 M# w3 tdouble b = 9;1 ^ s* r; Z2 O9 Q1 l8 ?
( N2 s; F" z, E0 g9 M7 k1 _
double c;/ L, @0 l; I+ Y* a
6 y; B1 V6 i p _! _/ t8 m
mwArray mwA(1, 1, mxDOUBLE_CLASS);) ~: B- R3 D3 K
! |! }( O( Z/ O, K$ g! SmwArray mwB(1, 1, mxDOUBLE_CLASS);
1 o2 P9 Z* N( ]( {; a1 N
* i4 {+ s) s3 ]- k4 T* ]9 QmwArray mwC(1, 1, mxDOUBLE_CLASS);8 w$ I" ?- [% b. s2 w& x6 Q
) V% Q# }1 O- O4 g- o
mwA.SetData(&a, 1);
8 f# q# [# K" T8 |7 x5 K
: W3 B3 q; X5 h+ Q- i0 ]: smwB.SetData(&b, 1);% q; v+ R/ d. }" u* k, S
, Y: _* H. X9 }MyAdd(1, mwC, mwA, mwB);) i( k: \: C: W; E7 L
. | {# r b0 Y, T2 a) f6 H. yc = mwC.Get(1,1);
0 \7 c5 s9 D& N6 g% L4 `7 b2 j" v- W/ R7 W* y0 C) r+ B* h
cout<<c<<endl;: z6 t/ O3 X4 U7 p5 t1 p
3 P& B8 W" f9 j; w. msystem("PAUSE");& K! m' {. }) |8 V4 v/ e5 a* g$ F
' C+ \# b8 S2 W4 L* w% H5 \
return 0;6 k$ k2 M" e; s: @/ L" z% O8 P
8 f U. `; l6 Y}
# m2 l# G- }# Z0 L m- x; [! S3 ~3 r7 v) N! D5 I3 E+ W+ c
这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。
2 S% |, |: @* L3 R9 Q6 v7 W. A7 h2 I6 h1 k6 [" q
#include "engine.h"/ L: R; J0 B( L2 ~
* S/ [! y! V; q6 K/ u
#include "mclmcr.h": `; |' \& c% H* Z# m
+ W; l: Y* S8 S8 d
#include "mclcppclass.h". S( C' ?* f2 r
- S) K: g) M" l( N S
#include "libMyAdd.h" 这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证): O# N5 Q/ ?: g& s
* E4 x) c+ [% T& J9 R+ ]! A
现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。 出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck to you!
( i9 x) T5 ~" P( @9 Y
! B7 p B$ x( j3 r. z备注:# c7 f- }/ V0 M" Y
" h9 ?" ~% l! G) S9 n/ V
1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。2 N" L ]/ X" A3 H3 f
; B, a' J& y1 i/ G# o1 L4 |
2.主函数代码中if(!libMyAddInitialize())是必须的。
; t% U5 F0 w0 W; Q# j) g! Z$ C5 F4 u, |8 Q; {& Q
|
|