|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载)
/ G5 ^! [# o. P* O) F2 W
7 |# F- ?+ K( C/ S" H整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7( }8 M4 v: O/ C8 f" F
0 J, J0 v2 _( P6 t ~
一,设置操作系统的环境变量。
! _) z- e& {1 \" b8 z# @$ X' ?6 ?$ m
系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
2 K d( p) b' e _
3 P# K/ C- v6 {( a% ?8 w9 w系统变量设置完毕后需要重新启动计算机方能生效。
; l* S; r/ O- s( D3 e) c7 r% {* m* i4 r! n: v
二,设置matlab的编译环境8 r1 J& h9 f4 V4 R; y
1 @( ]% Y) C" y% S0 A3 A
在matlab中输入命令mex -setup,选择Microsoft Visual C++ 2010
0 R5 M8 q4 M, e8 |* P& _8 B+ e3 T. ?1 h# B
再输入命令mbuild -setup 同样选择Microsoft Visual C++ 20105 T5 Z, `1 b+ k4 u3 m3 y
! V% @1 Z# j9 r7 C8 p5 u. C* np.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。
8 Y7 |, b$ ^8 J7 s" E O; G) j
3 |" e* }: w; M/ g7 u' \三,matlab编译.m文件& ~% Z0 Y+ X' J6 ]
0 Q1 w; Q) z( g$ G2 w( M3 A输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
. `1 @; S4 ^8 i" v! P6 w& f, }
Z, y5 V/ p* M( |$ H% n8 C其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。
+ d z, k% E4 f( q' \# S
1 I* [+ {, o/ l) |; h$ h0 p: c编译完成后得到了下图中的一些文件:
# p0 @5 Q, J4 Y% J/ F
! j5 A6 a$ y2 J* v1 y
7 C. S5 O% g! E
/ V' B% X- P j( c这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了); c3 g! ^$ m* I# y* w
2 H- c: x5 @- ]1 f% `' I
四,VS2010 的配置
+ {1 R; h/ r$ T+ W8 l# z
5 [& y# [6 L3 N8 X新建一个控制台项目。
1 T: K3 Y3 `6 b1 @
, |6 @+ v% W+ C+ A打开项目的属性页,针对这个项目做如下的设置:* \4 G2 b8 I6 z6 ^" s
% D2 @( y; Q+ X1.VC++目录下的包含目录添加8 ~- d1 Y( ] @7 U5 W3 T
2 s( }" d6 ]& f# H: A
D:\R2011a\extern\include(matlab安装目录下的路径)
|( {$ ^: {5 Q6 R% f
+ L6 V$ t* k* s( BD:\R2011a\extern\include\win32 (matlab安装目录下的路径,下同): Q) s+ g$ c- h* p9 {. `
' Y, Q& w3 D+ h- V5 VC:\Users\lenovo\Desktop\aether\aether (你自己新建的项目中的路径,下同)# E0 O- l5 \( I8 r0 z: Z
7 A% s8 ~) u% @- [
2.VC++目录下的库目录添加3 o5 d4 }! G! R0 x; C
. @: |0 i* {, u6 r1 [1 R+ Y
D:\R2011a\bin\win32
& j: z# u/ n- x3 t1 |+ n0 w7 i7 _( ?) c% S, y* s8 `4 P/ ?
D:\R2011a\extern\lib! r# V8 O# u0 [1 L' L
: ~( A# E& ~* o, Z* V2 m
C:\Users\lenovo\Desktop\aether\aether
. { y0 i' I3 t/ u& d
, \/ J2 O! x5 |! BD:\R2011a\extern\lib\win64\microsoft
- m$ Q; O& D- ^* u- m6 }% D! W; x# f6 O! K6 Q: O0 D
D:\R2011a\extern\lib\win32\lcc( n' N+ X& p# Y/ S% v
* K4 a" d. I8 y" r2 X
D:\R2011a\extern\lib\win32\microsoft+ A3 Z; D9 E: o8 N+ ^& }
4 }, V3 Y- i1 m
3.c/c++中的常规里面的附加包含目录添加# F# l0 ~0 g% A& `
" o' t1 u! K. u$ ]6 ^D:\R2011a\extern\include
6 W* b6 S$ b. B" M( V2 v
9 c; E1 C4 Q1 k) i* A, h) {* ]3 W' E4.连接器下面的常规中的附加库目录添加
* ^! E1 P* ]; D2 p
. r6 r) N" ~# u" M, a E/ k1 Q AD:\R2011a\extern\lib\win32\microsoft8 G$ x1 X' i8 g0 P; T1 B
( h$ f+ z: L9 R3 {* e5.连接器下面的输入中的附加依赖项添加' ?+ q/ f4 E) H$ @+ `6 y" e
3 ?- w1 j4 c9 ^1 i" {3 x; B) h4 Slibeng.lib
4 B" G4 D, n- J+ X' `( ]# } {3 u- ]# D0 H8 @+ |
libmat.lib X/ |# [* h) x% o- T! [5 \9 z$ ~
7 S% e* n4 V3 b8 Clibmex.lib
6 Y% G" |% }; i
* S- U8 a1 z6 \4 o# |9 P6 olibmx.lib% a6 m. T7 X2 x: G: z
$ h0 x6 V4 u1 n8 \mclmcrrt.lib* q# B2 P+ p" O& u( n
8 B+ f5 l2 }( b5 J- b$ v3 q
mclmcr.lib
. _1 S k" R. ]. C ~$ j+ M6 U E6 U; D' [) @& i2 a
aetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)
1 O& [: p$ d( o$ }9 Z
2 k- ^$ V* L& a. c+ A ? n+ I在解决方案资源管理其中的头文件和资源文件中添加文件
* E* S0 }5 G3 q) m- r) N
' e4 ^% ]2 X$ \1.在头文件中添加生成的.h文件9 V- V$ V* b1 m h/ {. c; R
3 l3 G9 M# I" `7 c2.在资源文件中添加.lib,.dll文件) d2 }9 n- p8 v, \+ z
+ l8 a: A3 H* {8 i) G- O/ X9 X5 U
3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。
+ G- m2 W0 \8 s) z2 X' k9 j
$ X, t) c0 H, ^(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C6 I) h! k8 G5 G5 c, o
1 E4 ~' c! }# V$ Y9 f6 o/ v然后把.ctf文件也拷过去。)9 v n+ p1 d% Q
% m" ~! D2 U" l. M4 m/ ~! A编写代码调用dll中的函数
! }. Z/ W& b1 ^5 @7 n3 y& o$ ^4 B/ |
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。
" M S* |( O5 \& a' O8 i/ u. m
: a4 I. Z5 L' B下面是一段主函数的编写样例:
9 s7 g3 Q" T8 k& A7 |' b4 Y4 z7 S0 Q; B2 K& p; |' V& n- h
// newdll.cpp : 定义控制台应用程序的入口点。
* S2 I; ?: \* y0 p( l$ f! C+ t! a* T
//5 D7 |5 [" Q Y# E! n! s5 K& G2 i
" D7 x2 c: Q9 C& h! i; X8 Q3 b$ ^
#include "stdafx.h"
3 ]8 e/ T3 d6 g( {3 E7 S! w3 I# y6 a9 v4 e5 p+ ^- _+ c, S
#include/ i2 T J* y3 B
, I* }# ?" T6 j; ~$ L) y
#include "engine.h"
3 v2 P2 D8 G1 S/ L8 k5 @ W; o7 O* ^* b) e! [
#include "mclmcr.h"/ U2 j5 {) z Y' y
0 ~3 t9 E" O9 g9 U, r
#include "mclcppclass.h"0 C. S9 N8 m/ j2 d5 [1 L" R
: z1 _7 {. S6 x& C, R: i
#include "libMyAdd.h"
+ |5 e/ G8 ~# r6 }3 [- `* }! e8 r! Q8 W% |+ ]/ k
using namespace std;
F8 }% {: L3 `9 V* r: l: d0 c" h. M7 G6 k
int _tmain(int argc, _TCHAR* argv[])
0 V* h, Y S- c9 g% Z' o
* u. |$ H" j. L: v+ ~5 }{
( P2 I( K5 R) U; a" t# y* f' l
& y+ s# i% Q8 B* K if(!libMyAddInitialize())1 }0 i! k$ y2 t/ B
5 l* N, U" a+ D: E) q2 v3 [
{
3 _/ W9 ]/ f$ C( [. i- L
( h1 q9 G: G% g. A$ p1 n; J) M //initilize failed!!!"<<std::endl;
2 b5 d& _* d' S- |/ e5 [6 n- n0 T8 p& T- {
std::cout<<"错误..."<<std::endl;
6 ]2 e( R/ |1 _, q( y9 @
}0 M% R' X0 I. j return -1;( L( s" _' P0 ?' ^# z/ {! k
* s! s! Q. K0 D0 @- m) G& R) V0 |% t
}
7 c) P! n- e; r# m1 p E- g, E" |7 t6 x0 v+ {+ e, J
double a = 6;
0 q9 X; W9 p; k H/ P" X9 B
* A* B/ `& R8 W% Vdouble b = 9;
2 ?% n' R9 d; F) K$ d) w e) d2 w ^
5 Y3 t, a/ P3 L0 @" t( {double c; u2 P" [4 T8 B( A$ ?
5 a4 q( k+ w1 RmwArray mwA(1, 1, mxDOUBLE_CLASS);
) Q# U) |( c, }% w
, S1 H; w* c& V; AmwArray mwB(1, 1, mxDOUBLE_CLASS);
% }0 N2 r6 Y' ]" O8 l9 } A( _9 ]; {+ w; ?. }% F- q0 I
mwArray mwC(1, 1, mxDOUBLE_CLASS);
- f2 [" N0 D) l! d
, i, K/ c: l3 t1 ]- NmwA.SetData(&a, 1);& l5 b: s: W/ t3 |
! _3 z: o) Y% z+ E& q0 tmwB.SetData(&b, 1);' y3 r) t; J Q& p, b5 D0 Z$ n3 I7 [
& n, S, T" M2 c8 J: D9 ]) u! L
MyAdd(1, mwC, mwA, mwB);
Y. ]7 @' I; E$ A. G$ b8 K7 U1 Y7 E) I; i: e9 F
c = mwC.Get(1,1);: {4 r' B% i# t9 o, U$ m0 D1 m
1 i7 }# d5 p1 F- ?cout<<c<<endl;
) W ]7 O0 [' n* P: A
! ~% ?" z3 z7 o" W* L! ?$ esystem("PAUSE");. o' \3 s& |6 i' R
8 c: Y: C2 B7 }5 ]9 E return 0;
) i) }$ N0 Q( G$ Y* t8 _7 ~. b2 T2 C2 J
}
* v) {3 X1 T8 a, n& z* m/ ~4 R1 `6 s4 a
这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。$ X6 {/ U6 g/ X1 T& F3 L
' \1 U7 ^. ~# P0 ]# p4 G, S& z
#include "engine.h"8 p7 g. q! I2 _
( E: i' {! h: o" R7 \' {) W
#include "mclmcr.h"8 U, Y9 O* A _; V# |4 n" }. v: h
! P7 m8 B, Q& d) g9 W& }: r
#include "mclcppclass.h": g7 W# ?, X# ]% Y
' L) ~: R3 n; W6 k ?" }
#include "libMyAdd.h" 这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)$ x1 I/ \7 ^( u. M( j( S
3 \$ V7 E; E) K0 i; B& H% V
现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。 出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck to you!5 U1 { D4 ^' P8 |1 Q
6 R0 L+ m* `9 _- ?备注:
6 [9 K$ o2 b& a8 X
3 \1 X0 ?. L1 Y) S# C+ H! H: P0 ?1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。3 f, L( n, T0 F1 q( g x
# e- O! ]7 m) E2 q7 ]% y( r- w6 B" Z 2.主函数代码中if(!libMyAddInitialize())是必须的。' \% m7 b+ ?7 z% @! q' I
, [" a. \( c; K! c1 d0 ]' x/ c
|
|