|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载) 8 K* t% a, k# g+ @1 q1 q. Y
' o- J; b9 A j" z7 G2 M/ V整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
$ y6 g3 t. s& E8 ]2 w7 m. |6 ?3 ^5 O
一,设置操作系统的环境变量。
" \" y+ U. @% ]$ M9 @
5 o9 W0 p$ g9 s) X, a" @% J系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
: o/ I3 r8 C3 F& Y, v
y! c& R( j" w3 n5 Z \8 u" n系统变量设置完毕后需要重新启动计算机方能生效。
$ q" X7 J% A0 V2 ]: Y. \3 G/ }7 |) |
二,设置matlab的编译环境
8 D) ?# E7 Q, }8 d( i
; w3 J/ K {7 e在matlab中输入命令mex -setup,选择Microsoft Visual C++ 2010* s; q3 t* v! l+ f
( m- ?. f0 o' \8 q! C, l8 I' Q
再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010
5 C' c+ w) m& r0 M* J' |" Q- a5 H! V0 [9 V( ~. J4 @
p.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。
, [- ]$ Q* V1 z1 O# G9 k7 a0 A
1 Z+ M6 `0 [4 c4 @3 b `, A三,matlab编译.m文件
3 S$ D/ G' K& H$ f; E" o7 S0 p: f* r7 L$ y$ h$ ^! _+ ^
输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
! u! x1 M& e; L* ^# W$ b4 `0 K" l( c% \8 Y+ \( r
其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。8 b1 r' s% f0 T! s
. n z6 p. _0 V0 M
编译完成后得到了下图中的一些文件:/ H; J. e$ d+ ^# y" u6 \4 `
& R% H4 t# _) J7 L) @! a
! L: z* x3 M8 G2 e4 }7 C: d* f! x9 g) d3 ^ {8 G
这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了)
c- S" p, X3 ]) A% D& m8 p" G# L/ A6 J& \7 T/ P! W
四,VS2010 的配置
1 }, T" ?1 q2 J9 h4 O% r2 d! g6 }8 W/ D7 R
新建一个控制台项目。
7 {, w& W6 H1 F1 ^3 V
" e5 u; d |: K$ {9 Z9 v. I& m' d打开项目的属性页,针对这个项目做如下的设置:4 M2 V/ ~4 V$ u' D7 L& D
7 `3 P1 P: N* S% A% r9 A% Z
1.VC++目录下的包含目录添加1 A. Q T1 Z# u) G+ P+ E
! `) l' R( L% N: @D:\R2011a\extern\include(matlab安装目录下的路径)5 M4 q" G' c) A& g8 Y# ~
% e' h; i6 {( ?D:\R2011a\extern\include\win32 (matlab安装目录下的路径,下同)) A! M0 m3 c7 h' j: g0 h
' [$ D( X! \9 G' J
C:\Users\lenovo\Desktop\aether\aether (你自己新建的项目中的路径,下同)0 i# r* k( `: ^9 o8 B
+ X; g1 s, u8 A6 G+ B2.VC++目录下的库目录添加# P# n4 |0 t% J0 d W: P
( l$ u( ]8 d, b7 d
D:\R2011a\bin\win32
* J) c4 X" C+ q4 j0 D4 U$ `6 e( s% E1 u, s9 i5 {
D:\R2011a\extern\lib* d! w) K0 i8 X( j5 R
# C6 z) l l6 y8 E2 BC:\Users\lenovo\Desktop\aether\aether
9 m; }7 m ^6 M6 [5 V" A
, n" A1 }# [! ~4 P9 `7 ]6 w2 Q& KD:\R2011a\extern\lib\win64\microsoft% x, x7 V9 x+ u7 X- Z: `8 G
& J: o' a3 t! ^4 ~D:\R2011a\extern\lib\win32\lcc
8 ~$ ]8 Z" p/ a
" V& j% R. u& d z WD:\R2011a\extern\lib\win32\microsoft
1 g0 K2 q* M) n8 u! T" ^6 j: B* F/ ~! ~) i
3.c/c++中的常规里面的附加包含目录添加
* T1 {' J. I4 E
9 L! O, _- d# \" D, n2 CD:\R2011a\extern\include0 B: s3 T8 M- `/ j7 Y0 R
; B/ h* K+ A+ F- ^4 R4.连接器下面的常规中的附加库目录添加
2 R5 ~7 z- Z2 N9 D1 d
+ v( \) m3 i L9 a( WD:\R2011a\extern\lib\win32\microsoft
% C; m5 z1 G; j9 O2 x- D( x
! w" l! G- L( t6 c5.连接器下面的输入中的附加依赖项添加; I9 |0 _6 ~9 e7 L6 v
* O/ o- K' W7 ^* @( N' H: z
libeng.lib! R- O7 Q* P3 k4 }' z% R' Q# o! }
- [' d& q8 o& nlibmat.lib i, o o0 [" F+ G. Q, C
h4 R" h5 q% f: @. klibmex.lib4 {( [9 k9 H$ @" |8 `
* @' i, a- {% y! [6 ?libmx.lib
N) s9 V! T+ R0 s9 @
5 C4 K) n) u4 f4 \. z @mclmcrrt.lib. t+ r; |4 o% v: S8 a
1 F/ d7 P3 ~" U/ G
mclmcr.lib1 ]: T+ c$ H4 N% H% B8 o6 T4 n w4 P
- E) H( A D- e% n
aetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)
! D4 P1 B0 [& L, J! q8 c; T" s+ j; V! V0 h1 @9 ]. c \8 t5 g; t/ K8 ~
在解决方案资源管理其中的头文件和资源文件中添加文件
/ h. t( l$ G9 j' Q( h" x1 k7 K
0 M. H) p6 R, G; |6 L) B! i1.在头文件中添加生成的.h文件
3 e/ Y. u! u$ K# N3 ^, ]8 ~/ ]* R
2.在资源文件中添加.lib,.dll文件4 k- k* k; u! z
& w9 C' F; E$ K$ s% W& [! l3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。
7 }$ x: P! d1 r: w+ z* _- D3 W3 y9 W& T
(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C' S, T7 `; Y! q! I! Z2 a
3 R$ v, e7 P' Q' N% X9 s然后把.ctf文件也拷过去。)
4 E2 x2 `/ t' i) A) ^( x7 u- o% w ~- E$ B
编写代码调用dll中的函数- u% H( {* W8 R, ?
2 k" b O+ c: q3 w
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。
( [! q* U; c3 V4 K3 `
7 v, n2 B* c# w8 |! x8 b下面是一段主函数的编写样例:) Z* H# b1 V& A" `* o, b
7 Z2 |4 c# a9 L5 S9 O8 b& V" q
// newdll.cpp : 定义控制台应用程序的入口点。( u# A: o3 m" x9 B. ~
: g/ T4 X/ l+ Z \//9 I. O6 ^+ l" c: v
! a( ~/ i8 k, Q6 ^" Q
#include "stdafx.h"! X$ o7 P9 Y; b+ [
- W7 n( x$ b) _ D$ X#include
( C/ T6 {2 E2 _) ^' N0 q
. t. P, L; O5 H3 b#include "engine.h"
, t* I9 T! ^! P4 Z1 h) h# P
. B0 K, g) L4 S$ M, D, Q8 y) M0 G#include "mclmcr.h"
0 Y; N) |* @3 n* ~* q. n
- d0 Z/ k" r7 p& q#include "mclcppclass.h"
* e! q& q$ C8 q) I9 f9 \2 ~1 ^' P5 f' Y: M/ x
#include "libMyAdd.h"4 i7 m* C' S5 s2 W
. Y1 ]5 \. Q! W( b4 l7 {/ V
using namespace std;2 x. K F$ s7 O! X
' b0 m: k( R* t, Z, i) N
int _tmain(int argc, _TCHAR* argv[])5 z% e0 v4 }/ e3 P0 g0 i+ k7 q
" s. j9 l% X9 Q
{
4 j, k( Y0 o9 J3 m5 }* F! N. d9 w" ? u6 S+ p
if(!libMyAddInitialize())
& t: Y' _. R* U, q: `
$ I2 }/ R+ ~8 n5 U: U {
8 k% F/ @5 T$ h" p
1 g% A" ?3 ~5 J) @" c7 W. x //initilize failed!!!"<<std::endl;
: s4 V7 H4 [, y8 s- Q6 X3 o5 v$ c0 t3 v W( M
std::cout<<"错误..."<<std::endl;
8 z: Q% x; R5 |
0 e: Y+ w+ \5 m# c return -1;( }! H/ U( l% t( {" A: X
7 c$ b! R, T- A! ?/ U }1 E6 F0 x7 M+ x$ r3 y
$ f4 p2 i2 w6 J( R+ F# X' j
double a = 6;. @2 p+ l+ z. v% F. U! G( s8 Y0 c0 m
2 t; R. t5 C' O( p- q: O; X4 adouble b = 9;
2 o6 X% f, I2 n. m |1 k5 H$ l1 q8 n
double c;
v: K& W$ ]) c2 t9 Q
$ o- \( q5 Z# ^$ umwArray mwA(1, 1, mxDOUBLE_CLASS);' @7 o' I# Q, A
) j- Q3 P2 v- ?4 p+ QmwArray mwB(1, 1, mxDOUBLE_CLASS);
; r/ T) w G( V* }
' ^1 }; F( v; X8 }# G( ]mwArray mwC(1, 1, mxDOUBLE_CLASS);
z; T/ G, e' j- t& w& w W* @2 ]
mwA.SetData(&a, 1);
( @. b( `. c* f. b( \: Q0 b7 s
: q6 M. a+ l" B. amwB.SetData(&b, 1);
1 g7 @5 y+ P% ]. o# Z' Y" J3 z/ N- ~8 X- Y/ t
MyAdd(1, mwC, mwA, mwB);
" ~; ^- `( F8 o, A1 o! K9 L9 `. U, ]/ d* [9 C+ p
c = mwC.Get(1,1);: t2 W. m6 [0 ^! P. ?- y9 G
6 R8 s9 y7 E7 T: D( A b" Tcout<<c<<endl;4 s+ I, \. s: t: n! B9 z
% M6 ?" g" M8 b7 |& y* A6 R" V
system("PAUSE");
. ^$ a; C2 l" s. [; @/ e x& B0 |9 a: k7 B' Y
return 0;" G. `( }; A* l8 c
: }" c. A) O9 c- z; v% ~$ j7 J}
5 }" X/ N9 c) X7 B- V1 ^" h
8 I3 m4 I, e D1 p$ W0 e9 l) Y( \这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。
3 n: |. L8 R1 Y" h% E( o/ l# b
3 x" b8 |8 J; S# t #include "engine.h"
: k$ ?+ c* f1 e
0 B6 j+ B# f) C: u" ~9 `#include "mclmcr.h" }1 v/ ~+ W3 D0 k3 V
6 [7 |0 J6 d2 g1 t4 _+ o3 f" S) V
#include "mclcppclass.h"
" d7 A/ ]! k$ }" T! I }; h) d$ |
#include "libMyAdd.h" 这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)7 i$ S- H3 ?; U$ b, P; M+ R
+ K7 W- d& N }- v现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。 出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck to you!8 ~2 L+ w/ w% M) y4 r7 v) F$ U
4 ^; A( `1 J2 @( ] T* B备注:
m% Y! `& K3 h2 R7 _" P; b6 e% S2 [# r, M+ A% M$ J( }
1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。) B' e! c5 O! h8 M+ c+ [4 R/ y
% |% g/ j, Z2 i$ U; c
2.主函数代码中if(!libMyAddInitialize())是必须的。6 L1 Y) p$ s' F% p. ]: P5 ]) H
+ T; V; n8 T2 Y2 L/ F |
|