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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载)
/ B/ C0 l+ ]$ r6 |3 V6 y6 x  [" h
, ^& {( d0 Q5 c- a5 K8 s! w整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
' R. M% ]% \8 N3 Y
' s6 O6 x7 n! `一,设置操作系统的环境变量。
* u: p" I7 @5 q5 n9 A' l4 H- |
1 u1 f. G. z3 w- y系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
) E* K. L0 a" ~& u
% C5 k5 F) ~! ^" W" T系统变量设置完毕后需要重新启动计算机方能生效。
/ Q' R7 i0 z# T* \
* @2 b4 _) e+ X1 G7 G, r6 \7 N2 j二,设置matlab的编译环境
: P7 U4 y7 n( [+ v
. a: s2 B/ ^4 }1 F7 R  H; }6 k在matlab中输入命令mex -setup,选择Microsoft Visual C++ 20108 L' t, T7 H5 \  P: |
" P4 Z! A2 x# Q$ \4 T$ ?( y& K2 E
再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010, f# I' w7 h, p( d

1 E6 I# B- }$ Xp.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。
6 ?' d5 _& ?; C! x
: `- M* A0 {) _: Z( I三,matlab编译.m文件4 E' G  E, e$ [" u6 Y

' I* A; q" ~# O: r输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
1 q  s/ F0 B0 h! R. f8 M$ j0 v" n" M0 A, o0 [4 e
其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。
: n( I- B5 T$ R( [* T, i9 X: ^2 E, s7 Y' h; ?
编译完成后得到了下图中的一些文件:
! O3 B8 Q+ T/ S8 h) n
( E' q+ X; b( H0 ~. ]& g- `" U 0 T" |# r- I% V; X% o+ U& D

& v- c' S" G  G* V! ^" C, E这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了): [# R8 ]% F! j
* U4 _& z# Y( R3 I9 v/ R" o
四,VS2010 的配置" ^% ?+ _6 L6 `- Z

- \. F2 @* l5 H/ [- P" f/ [1 D8 B新建一个控制台项目。
" ]! P; k  q0 H' j5 ?( p
  d+ K, o6 M" x( k; _. Y" a打开项目的属性页,针对这个项目做如下的设置:. p$ [0 m. ^% y. K  Y) B
' l( |! C: ?' H* R; R& n! `3 C
1.VC++目录下的包含目录添加; j5 s2 h! m5 Q1 q$ k; s

  a5 ~7 b# }  ED:\R2011a\extern\include(matlab安装目录下的路径)/ T; D# [  H1 t

6 R8 M4 q" \' G7 u0 v) oD:\R2011a\extern\include\win32  (matlab安装目录下的路径,下同)5 p# ?# k$ O  U$ |
/ u$ [1 H* }/ o4 H) ]% U# Q" L# o
C:\Users\lenovo\Desktop\aether\aether  (你自己新建的项目中的路径,下同)
% m* J. B! w0 u/ g
* i. h# D, z" B2.VC++目录下的库目录添加
9 b, t7 c2 b3 c9 U8 b& }5 e, ^1 {, \* r* n, h6 b
D:\R2011a\bin\win32
" w* h) a% Y/ ~2 o" K' ]8 {
1 S( K& i- {; X' {# ID:\R2011a\extern\lib! |7 G1 t4 o" N3 g
. {& X( M; c  `! ~
C:\Users\lenovo\Desktop\aether\aether" _6 t/ Y* u# F: _1 F" s; |) e

3 G4 R/ b( z( S6 B( jD:\R2011a\extern\lib\win64\microsoft
7 E7 M+ I1 g0 u' D; g4 H$ @2 x% u1 _' p, g( e7 B
D:\R2011a\extern\lib\win32\lcc
, B. g8 ^/ D3 ~8 b7 T, P% Z' I% M& }6 N7 N
D:\R2011a\extern\lib\win32\microsoft7 L2 i# ~( ?4 i- t
; }0 s. [+ `/ A  Q
3.c/c++中的常规里面的附加包含目录添加
9 L6 o3 r( U3 I  B5 ^( k/ `; Q& z1 e3 U* K, A8 @# y5 R8 D3 w) Y
D:\R2011a\extern\include
+ k9 j' e$ j4 V; i
5 d# K  n" ~$ X7 p4 _/ |/ `; P! X4.连接器下面的常规中的附加库目录添加
) e* w9 \8 p" P
  E6 Z/ w* B$ Z6 h2 D' e4 }' ?D:\R2011a\extern\lib\win32\microsoft
$ s# H2 a; l! @8 q: A: M" O/ }+ Y$ l0 `6 m7 Q" |
5.连接器下面的输入中的附加依赖项添加2 s' v1 l" X' s* `

4 b8 z8 B- n5 R# D; R0 i: Slibeng.lib
; O9 I/ @# ~+ N9 y& P/ p# E  H# S/ D; Z" W3 ]
libmat.lib* t! t" f0 `" m) Z2 K! C

0 g8 R% r( \8 f7 R( H8 Klibmex.lib' Y+ o' U8 ~6 B' L& S

3 Y4 \( L. R$ C+ ~libmx.lib1 O( `2 u6 m* |$ F; [" R

6 s( m4 f$ s8 ?9 w$ O# E* Smclmcrrt.lib2 ~# v, j% `, Y$ L

3 y3 D2 X; U' Jmclmcr.lib& T- ?/ I% {$ B
1 X  u; w- L' I4 k3 ]. c
aetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)
9 E  a  \3 q  ~2 T; M1 w7 O. G9 `8 v
在解决方案资源管理其中的头文件和资源文件中添加文件
% `3 H7 ?. k3 F: A
/ f( H7 ]1 G+ {1 x# q1 s1.在头文件中添加生成的.h文件
1 B/ M4 L6 w% V' u  ?9 |
) o* E& _- V  Z/ p2.在资源文件中添加.lib,.dll文件- w' E6 R/ j, u, ~" u
; a6 o1 a' S. j  m  W, `4 H, H, D
3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。# \7 {# E) Y7 J! I& g( C7 T( T$ L/ S
  W# @! S& Y% u, {  {( k
(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C
: s% B, h1 V9 g7 D) K0 d, n1 s! F5 }8 m& u# E+ a. y8 i. A: V0 k; t
然后把.ctf文件也拷过去。)
; s& }1 o! N4 T* D$ L2 X( y5 d& |5 i. e* `1 c5 \* K
编写代码调用dll中的函数& s; N8 ~3 Z7 P% R# j9 E7 P4 v

7 _. V% M# @' x# Edll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。, |7 }" X8 E+ @- A6 I

4 ^: M; K- c$ U* [3 R3 o下面是一段主函数的编写样例:
: n7 R! N' R2 j- Q2 j4 E
3 O! ?8 k6 F5 m8 D( m// newdll.cpp : 定义控制台应用程序的入口点。  b( r5 |! Z( H
% F, o$ b# U# }! m5 b; K% n
//5 D8 p. Z7 T% X

( T! h8 j9 s# z5 x+ @7 D( p#include "stdafx.h"
0 R* N: l( D  w
3 d5 J1 V. ^/ G+ q#include9 n: x" Q' T  t2 J+ L; W) ~1 r
' C+ T' r% |  [$ l* B
#include "engine.h"
# _& u4 j, I1 B0 j3 T! R& P2 C" f( w6 t
#include "mclmcr.h"* _- }& f9 I8 ^7 q2 y
4 M# B5 c  v0 x- |
#include "mclcppclass.h"8 {$ U0 \! Q- o

0 B8 P/ u! C, n#include "libMyAdd.h"
5 C% F4 y+ i; R) i: C/ F
! |& \% c* d, \" ?) ^using namespace std;
  I" b# @0 z. A$ G- q+ F" m1 ?& Q; v8 e6 w- T- p
int _tmain(int argc, _TCHAR* argv[])
) J0 ?! b; N, Y6 G5 ~
" M8 P' }  i( b4 }' |9 g{
8 A* I: `$ t4 n
+ {$ ]$ i$ ?; k" m* w3 m if(!libMyAddInitialize())5 t" h! ?5 @3 ?  r9 {

  h" K+ C9 X/ B# X: P2 P& c   {
9 ?. i2 Z0 U, P1 h2 `  G+ `) d! ?% S4 J2 s2 A. P
   //initilize failed!!!"<<std::endl;$ ^" Y9 K+ S& c9 }; ?1 R

/ U: x, J  ?: H5 z/ X" ~; T6 m7 R    std::cout<<"错误..."<<std::endl;
  c6 r, v+ z5 D7 f1 {: |" a7 L
: @3 U3 ]* j9 A8 J( l) T1 H   return -1;& O/ _( L8 R4 g. y1 l4 S; G# ]7 b6 G+ }
4 a; v3 i! Y; K' t8 w& }
   }8 ?; X* Q# D2 k5 S% q8 g

+ N! ~* z0 k, n+ d" }3 U8 E double a = 6;! |( F; C) A- W; ~- S2 j7 R

% M" H2 g$ m3 y' |0 Idouble b = 9;
/ @9 w9 e) p8 W" G- V& H* F% h* E4 s- F% V7 g6 Z
double c;
9 }3 E& T( Z* z/ C: M4 M
  n: P* e; z! _. u; s# S6 b! }% GmwArray mwA(1, 1, mxDOUBLE_CLASS);9 X9 \# N; T' `4 f/ ?  r

: i- M6 A# K- _" a/ e( omwArray mwB(1, 1, mxDOUBLE_CLASS);. F3 c3 @. D0 r  O$ D5 I: k

1 c) \' U1 i+ C& y' W* a* D$ B: FmwArray mwC(1, 1, mxDOUBLE_CLASS);0 y$ E$ d) X- f# \  L

+ z( G1 h7 ?9 R# B5 _! Z' ]3 TmwA.SetData(&a, 1);1 ^' o% W5 I4 f& Z9 H) }

# \& |7 T+ X1 K1 g3 MmwB.SetData(&b, 1);" |3 r7 j" a5 G  u+ M, t- e

' @. }6 [, V9 A1 |* G3 H& M2 z6 FMyAdd(1, mwC, mwA, mwB);' g) g; E8 o6 R' N+ `5 q8 t* |+ k
/ X4 g( g: C8 z' L! H  F
c = mwC.Get(1,1);, M6 X' G7 _4 ~) F, k$ Y7 A" w4 `

+ d, a1 c# S/ `- Fcout<<c<<endl;
( |9 M7 s0 J  W' @# S
- {8 S2 g8 g$ n& T% Hsystem("PAUSE");
9 R. f- [; R, k
% i0 G4 ~/ {% N2 E* e return 0;1 K2 Z0 b1 r" c6 a4 J# Y9 x) D

) @, l: l1 U' J! C9 u: J}3 x  h0 k' J% p
8 P8 w. f7 a& [) L
这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。
. m8 ]7 z) }& o* ?$ p) T! k4 y. z# u, S9 F- x$ d( d2 u- j
#include "engine.h"8 I, P. B! m2 u2 x- a
$ A- H4 X, q! l+ O( B9 @" F
#include "mclmcr.h"7 L/ {! ?: m) N% ?# {2 l
1 ]2 o/ _$ V, O6 Y
#include "mclcppclass.h"# Q: Z* K/ @' h6 N1 g; c/ E

( l3 S* F$ V& e% H0 K/ t' x#include "libMyAdd.h"       这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)
3 ?1 L! s6 J4 A2 k# @, }: s, S
0 P, ~1 V# |% W3 h, g+ i& M现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。  出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck  to you!
% B: r9 I. |2 [# c* m3 U1 m* a  v* ^" |: d+ e3 ~; a
备注:" o8 T! m: Z4 }5 m

+ H3 V1 y5 x  u0 \1 _1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。9 |7 e! |, ?  c1 K- q
$ A1 ~/ J# r9 V6 q& L9 t
2.主函数代码中if(!libMyAddInitialize())是必须的。
$ K8 B$ Q  n1 X! r9 F* h! d
/ O; t, J9 L8 J

该用户从未签到

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-1 20:25 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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