找回密码
 注册
关于网站域名变更的通知
查看: 521|回复: 2
打印 上一主题 下一主题

再用VS2010调用matlab封装DLL动态链接库

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-1-6 10:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载)
4 ~! `1 t0 w- A7 D( X! M7 c% z& G) t8 ?
整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
% V3 U1 d! m! ?' h5 M7 ]3 C& V9 U! w# W2 X0 R* ?
一,设置操作系统的环境变量。
- u" v/ ]9 ]6 g9 P. H+ u4 |6 N4 x+ ]
) h+ I8 c$ i: `1 T# P7 s系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
7 @( D- Q2 F; }" r( ?3 ]; v8 T
/ s% I" c) k2 D1 G* @' z' }系统变量设置完毕后需要重新启动计算机方能生效。- X& e% N4 R5 S5 v; H8 \
& u6 e: @! G9 I: o' h
二,设置matlab的编译环境. @. m3 ^( q: J  ^; `) N
/ j9 D0 |! q* A7 I, r
在matlab中输入命令mex -setup,选择Microsoft Visual C++ 2010
( [2 z2 Z6 P+ b6 x
& L  l$ m/ L! B0 I再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010  |  @3 v! F- G

+ O1 ]4 W. d1 W+ u+ B" S. tp.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。
7 y4 o6 Q9 I8 L
' L- |* @4 z  ~) t4 F$ M4 ^; }三,matlab编译.m文件" d( @7 c% O+ l0 G! }7 E
, A, L' U) |( N0 p2 ^# ]
输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
: o5 h0 B* Z: V# u( J# Y, d# S6 M* P7 V7 {9 p
其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。
8 t  Q6 d6 p# J6 y' D9 Y& I/ G3 m3 u6 G8 l4 R& c( \
编译完成后得到了下图中的一些文件:
8 ?7 ~( H6 A/ h& D. n0 I/ J, y2 `! R

* Q. Y- c2 n5 }& Y- j  H6 G+ H3 B! v- _1 ~* ~1 ]
这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了)
- k$ W' l9 P+ y& [$ \" z; E6 s( Y, x
四,VS2010 的配置
( e! m. _9 L  k, ~; S6 s
: }* h0 h+ E8 A3 `' u新建一个控制台项目。6 U0 ?2 F  p5 M5 z8 K

. J, s% p" o8 n+ F打开项目的属性页,针对这个项目做如下的设置:) ]* [" u+ }2 d( f# h
, d2 U- ?: S, z2 Z& g0 v* I" h
1.VC++目录下的包含目录添加
8 o8 T" w5 s  z* |$ x5 k% X/ d
, N9 L6 k4 ~2 L, Z7 E/ kD:\R2011a\extern\include(matlab安装目录下的路径). O( ?2 f' `3 b# D
3 M! g* ?. d- R
D:\R2011a\extern\include\win32  (matlab安装目录下的路径,下同)
& |6 z" k3 p, u  d* D* C; ?% k1 a& j6 }/ N* D' P/ K
C:\Users\lenovo\Desktop\aether\aether  (你自己新建的项目中的路径,下同)
% P: V8 G. P2 [' V5 W" A
0 n5 b7 v# |* @" U8 D) Q" a& x1 x2.VC++目录下的库目录添加
* e" A! M- _! j+ s0 k- k/ r
# M1 s0 Y+ K, U5 B) v  u! S! [+ }D:\R2011a\bin\win326 O$ N2 p9 `$ ?6 J, I  i
& ^/ ?' E  ?; S
D:\R2011a\extern\lib7 L6 [/ N+ O* _& Z, C0 H
9 J9 \# p. y7 M! |7 ]5 h
C:\Users\lenovo\Desktop\aether\aether9 C0 X4 w% h& h! H4 W; w. ]" S
4 x0 V$ V* [- ]  d" \) M  {7 E8 S
D:\R2011a\extern\lib\win64\microsoft& I! R! q* y4 u% j7 H

6 s+ s. f& ~) d7 k6 F4 p3 ?D:\R2011a\extern\lib\win32\lcc
/ t, [5 B: E' A" t$ N; |; i
: P/ ]; G- u' }5 W- v- XD:\R2011a\extern\lib\win32\microsoft
5 e) M( ~. N: |, w& C% v7 V0 i4 c5 h, J
3.c/c++中的常规里面的附加包含目录添加
" o% ~8 R5 H7 x* _
/ _8 B! y$ L" i$ c0 ]D:\R2011a\extern\include
' X: }. z. F. T2 G: }, v
" Z! F5 z% T; i5 g4.连接器下面的常规中的附加库目录添加& n, p. o9 `5 X4 c7 r# u

5 P# c" G) C6 t8 O4 u2 mD:\R2011a\extern\lib\win32\microsoft/ J' |. j+ r& J8 D0 J/ p" h
" B! j5 L( A+ P/ ?
5.连接器下面的输入中的附加依赖项添加
" p+ w: |) G+ ]
7 u/ D7 k# u- z7 Zlibeng.lib5 a3 L: t5 H0 p. L3 {. s8 z2 P  R
6 s7 y; `$ ~* g
libmat.lib9 |" R3 @& ]& h3 ]/ S; s6 V5 `' a. M
' F* R6 N- p" s* a. q% i
libmex.lib5 W2 @2 Q) J5 Z  e8 M

( m! j) U/ K( M& u1 blibmx.lib0 T! V4 e$ t  R/ z2 h7 w0 ]
5 D& y! A; j7 v: ~
mclmcrrt.lib
, X& D! T3 U, }. O
/ m- ^; e; }  r; _7 C* j; V3 n- qmclmcr.lib
3 _+ L8 h: E7 r/ R4 M" R% R* H% l3 y9 }! ?
aetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)6 `9 ^% r8 L* A. i" `" C9 \9 a' N7 z# b
# d# X7 u. w, h9 r  G4 e' f2 m
在解决方案资源管理其中的头文件和资源文件中添加文件
) x0 a% \% H/ C$ x. d
  z6 ^) Q2 w( X: G6 M1.在头文件中添加生成的.h文件
6 c% N# ~  Y  C0 R
$ d, c! M0 j2 P, z  p6 L2.在资源文件中添加.lib,.dll文件6 X9 v0 `* X  o* b$ _# b

' _4 A+ z( Q1 N- v- r+ X& z! ?3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。
% h. e8 U' z- s; E& x# h" e& a2 ?) r/ S+ Z3 b7 d% k; e2 q
(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C
0 ^0 Y/ ^/ E, t( n( T1 P, m$ O; t/ B' U& E; e, s/ \
然后把.ctf文件也拷过去。)6 n) ?* R: k; Y& Z$ {0 \) p  p
8 E- y& K3 a# H  e# k
编写代码调用dll中的函数
9 w, ?/ }) c# p4 W4 E; g* a# c  a3 E& n+ _% G1 J  f$ u+ ~
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。
1 B3 L- }( i. }% m! h+ m! y% [& E" Y
' L8 j% K2 q7 s: L0 P, B# N下面是一段主函数的编写样例:
; z+ r$ Y4 a/ E+ w4 z# Z/ ?6 g3 n; h
: O. c- I. D; k0 D3 Y/ I% Q& M// newdll.cpp : 定义控制台应用程序的入口点。
( u  p+ V0 n5 a0 ~! t' L
3 K$ u! v0 @' }- y: W  g0 j" B5 e//
8 ?( |! }. ^( Y" S
: R: s9 D, ]6 N0 {+ l7 K#include "stdafx.h"8 f; ^9 V. h% j

0 \& l0 u( j5 Y9 p$ w; |#include
# t; E: e) p" ?' \1 J
' }( f6 G. L4 h8 I#include "engine.h"  X+ z1 b5 Q9 s
" s9 ~; n9 g2 [' l  [/ S
#include "mclmcr.h") l7 ~2 ]* W( v6 m* v
( E1 i' q1 j% g. _; U% H
#include "mclcppclass.h"5 L3 _$ ^! P! S( E! m6 S) C

+ V( U1 W! Y- M* ~" v) g5 Y#include "libMyAdd.h"
) w; ~0 |/ {- M7 U3 u) y" o6 e, L# s9 m# o4 g
using namespace std;
, k6 R2 e6 G6 J" p3 W, H" z9 j" v2 U+ b, ]( b
int _tmain(int argc, _TCHAR* argv[])
; p8 i1 o' L' p1 \8 V2 Z
" j$ b& t% Y9 y* g: G{
+ H( ]7 p# m9 R' R  m+ y! n8 K$ c5 O  e; M. U
if(!libMyAddInitialize())0 \* @, c4 M! C3 M( Q0 W

5 D) a9 N: g8 @" `% E   {
  _* X+ h0 n- @* N3 y* s3 G3 U2 r2 a
6 ?! g9 t  D2 `. \9 {/ ^; G+ m' I8 t   //initilize failed!!!"<<std::endl;+ S5 R+ U( Z) I8 F8 g( f* S! K

7 o/ e/ N5 m, L" \7 C5 ?% Q$ ^5 U    std::cout<<"错误..."<<std::endl;1 c1 U& |) D1 }% V3 q

) ?: M; `+ T0 t: n! u   return -1;
- F, R  X- ?% K- b
* w/ s0 Y3 ]  o5 E   }
# u2 {% b4 o$ P/ O# ~# g0 O, V+ p; O
double a = 6;
! D& j) D: a. H6 [. u9 P
* l( n, e5 {% ?- S. |( [& X* A& fdouble b = 9;& z9 K+ F! n+ L; y
3 r7 v' e2 z5 i$ ?. B1 E. Q' S
double c;
4 A3 y- g; h9 O$ K+ `% }' \2 V$ L/ X1 h5 a, [
mwArray mwA(1, 1, mxDOUBLE_CLASS);
3 P; J: g# M; z- q$ R: ^+ J, W) x0 i: n" u1 [' \
mwArray mwB(1, 1, mxDOUBLE_CLASS);" w# C" E3 Y  c+ R" ~5 N; f
$ C4 [- T% F) o2 ^/ Y
mwArray mwC(1, 1, mxDOUBLE_CLASS);
8 I2 \( t# h- E# y0 V: T0 f7 F. S& J7 f/ h3 H  N
mwA.SetData(&a, 1);
( Y% C8 }% X- m9 g1 g1 z7 z/ |' R4 J/ c5 m
mwB.SetData(&b, 1);
1 n) y4 ~1 ]" o; ^. ?$ ~4 L2 u% x
  H* k8 Y/ ]' k' kMyAdd(1, mwC, mwA, mwB);
" \1 y2 A/ d8 V- {' y( e. w* B; ?  V' L- c6 j
c = mwC.Get(1,1);5 B$ W" g1 N8 D, n" r) P

, Z/ V9 J! z! P5 q7 Ncout<<c<<endl;6 s" n& T' N$ c- F: v) U
+ P* @$ m  a1 S' b2 k* w" O* R" z
system("PAUSE");) x, {( i% `/ D3 ^0 n
4 ~( c! _2 R7 c  h9 a7 P
return 0;
- t! w; x! k) V) h  N! G1 b- F6 c$ ~/ ]3 M2 j3 l  N
}* B. v" G4 Y0 n/ S, N; [
% _) e7 o1 j  n3 y+ H6 N
这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。
( w" T4 R( `/ |# W/ m- j; K
' R. c5 r. k5 Y9 Z& ^3 c #include "engine.h"
5 H0 F3 q. S/ Q0 ?6 m
2 O' Q0 U) m; j; a9 F#include "mclmcr.h"
( c% m9 A3 W. _; d( c1 n6 X3 ]5 j; o7 Y5 W" D4 N+ S$ d' {
#include "mclcppclass.h"3 M& |9 I6 G1 f- h& i# [
' |7 [1 u/ [) |/ b, n6 [. S
#include "libMyAdd.h"       这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)3 P8 v2 d! W1 \5 E6 H. m# z, I

2 N4 Y: T2 E* o0 A- N: X现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。  出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck  to you!4 H2 l- _: R  n2 R- V$ f
9 L/ p, \& }1 z3 }2 N
备注:
3 z3 m5 `- |+ n1 z
# p9 t+ Z; a3 b1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。% P& M6 A: h2 |

+ ^: s, ?9 F! Z4 Y/ j- C$ A4 j 2.主函数代码中if(!libMyAddInitialize())是必须的。5 P: i$ Q1 w) n3 k3 M. [

6 o0 ?# W7 Z; V2 b/ k6 D0 o

该用户从未签到

2#
发表于 2020-1-6 18:40 | 只看该作者
看完只有一种感觉:学海无涯啊

该用户从未签到

3#
发表于 2020-1-7 18:06 | 只看该作者
用VS2010调用matlab封装DLL动态链接库
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-23 23:10 , Processed in 0.218750 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表