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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载) : U3 z8 K! |+ P: ~$ X: Z% c( ]
  v( r, U* i! R7 ?5 U
整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
2 ?# N+ T. k6 b- b8 v+ t2 Z' x) }) Q
一,设置操作系统的环境变量。
2 ^2 t; |, \! a! \, s% t  I! _/ `
; M7 t- B- t+ K1 `系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
" X1 F! d& E& T9 {9 ?* ~) o! D( B- t( G; @
系统变量设置完毕后需要重新启动计算机方能生效。" J' U' P8 s3 w) j* X

3 k( [; Y5 v1 |二,设置matlab的编译环境
% }+ V2 W1 `+ ^+ [
0 B3 z7 H8 z' T; @+ x3 G) i在matlab中输入命令mex -setup,选择Microsoft Visual C++ 20103 R1 p6 S! q' o  j
9 y1 R4 V4 }: x' i5 D7 e
再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010. J# ?# W8 [0 L$ E7 A0 f5 `
+ F. w! y; h" n
p.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。
, l! x# Q# c8 Z/ K2 X
/ @1 x+ c+ R& m' L, J三,matlab编译.m文件
# l  u! C/ o- I6 t# ^% \% x
$ `2 t: |2 T4 h$ R+ s* }输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
: Z. z7 u: ?" [: G6 Z
+ I, W- a  p5 X) j其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。
+ |4 B# c+ W8 ?# Y1 e0 b1 d; z5 `6 q! ?2 Z" _$ P1 O
编译完成后得到了下图中的一些文件:
) o) |# s/ J2 O, k$ O* f- W* T& L1 E5 b; {6 R( R2 j& S0 @3 G
5 m' y7 |  n7 s& ^
, P, K. {+ x' O4 E5 Y' P6 x% I  [
这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了)
9 }2 u# \# @! J" ^
3 r: [8 o( v% U四,VS2010 的配置3 d  q, ^2 V& n5 L$ f6 b+ |- m+ U

- z; [  }& [: `6 ^4 [4 _( t9 X" G新建一个控制台项目。
% P0 `0 z4 ^2 ~+ T3 I1 k4 W. S# d4 S1 f' u
打开项目的属性页,针对这个项目做如下的设置:3 w4 K7 t5 ~: `- L5 ?

( }' K  K5 Q! L% p1 W. R1.VC++目录下的包含目录添加! Z$ u1 W4 T& A2 g

2 D/ b; W: [/ x4 k  k5 t& bD:\R2011a\extern\include(matlab安装目录下的路径)
; ?7 ^  `6 Y9 z8 K/ K
6 ?: g5 E5 n6 ~9 o. yD:\R2011a\extern\include\win32  (matlab安装目录下的路径,下同)
( g6 C' t  L. R: O/ [( }8 Z( G* J# u: y; N9 J: R) a! J& U/ O; z
C:\Users\lenovo\Desktop\aether\aether  (你自己新建的项目中的路径,下同)0 J+ ]" M* _, x. V4 ^, `  }: n7 W
/ p/ b8 `, R) W. o" J9 F
2.VC++目录下的库目录添加
* ^  z+ a: K7 j& d6 }1 c& _% N7 z- b! A; U1 P
D:\R2011a\bin\win32
  L+ b0 E! O8 h) r9 s: a; e8 A& w/ g7 Z' ^# Y4 _0 @$ k* V2 ]( \
D:\R2011a\extern\lib
1 Z- E& u* y: l
+ `) ?$ s/ _! d8 H; M( Y8 nC:\Users\lenovo\Desktop\aether\aether( s: P( A* C3 X
2 Q' \# w. ^; n: F! e4 J
D:\R2011a\extern\lib\win64\microsoft( J: A5 k9 Z" W  ^$ i

  }0 N! r/ ^8 kD:\R2011a\extern\lib\win32\lcc
' p0 c+ Q" C% @7 l' |4 W2 c) Q& y# s) @% P4 @
D:\R2011a\extern\lib\win32\microsoft1 Y- y5 q% B% ]7 H( s
7 l: U3 x' C5 v+ k: v! K
3.c/c++中的常规里面的附加包含目录添加
  T8 u( D+ d* G8 t' Q6 f" Y! T/ Z" H# r+ Y, I
D:\R2011a\extern\include
* w& Y+ ^! v5 Z, ]
# o/ S- c9 k0 K( V3 Z+ e" B$ \4.连接器下面的常规中的附加库目录添加
+ C0 D/ ^# R  l/ {: S/ G4 ?: ]% Z' g. o" ]9 [) n0 r, Y6 `
D:\R2011a\extern\lib\win32\microsoft
( B) d7 P5 _4 w& y! W. l1 y# k% B
& |5 |$ X$ O# B; |# \5.连接器下面的输入中的附加依赖项添加% ^/ S" m! P" C' w- J$ ?
2 _6 ~  e9 F& e
libeng.lib
, s4 `4 N8 M" z6 g& S
1 @; j, F/ V5 Hlibmat.lib
7 J4 |- J9 X6 @5 Q$ _. c: c' w
! C6 }( ?( t9 S' [, S5 x$ h# Alibmex.lib+ R3 c: k6 ^9 T( w
$ t& F7 S$ @7 z- P
libmx.lib& ~; J9 |. I* F1 o! k' r
0 n5 {* q) Q* y' Q/ Z4 w4 k- b
mclmcrrt.lib
/ e* T+ K3 e& s/ O+ H- g: w
7 g5 g7 M1 o! ]* d6 ]/ ?9 amclmcr.lib1 ~  B2 m8 |/ I/ {- L

" c0 n: v- C7 G' v! RaetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)
  b/ O. Y+ \& F5 ^% d0 p
3 `) t  N6 ]+ q( m在解决方案资源管理其中的头文件和资源文件中添加文件7 r  x0 P( ?% @/ S% \: X- m
/ E+ O# \) M# {5 ~) H4 L
1.在头文件中添加生成的.h文件
3 c, E4 [5 g! x" A! b& R0 ^! D3 O" g8 q6 d
2.在资源文件中添加.lib,.dll文件1 t1 ~4 h9 `# c) k. K$ b: R+ u
* ^- K  O- y2 b1 e# l
3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。
. f3 T4 F: f) s7 b5 W. C8 ~1 t8 ]: R. d, W3 ]4 y
(最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C. j- T" W  K) m3 ~% F: X7 t
8 G3 @2 ~) b: e+ o0 e# J
然后把.ctf文件也拷过去。)- W5 U! u; _. z) Z  b6 V9 h; L2 _9 P
( z5 q: |3 m8 c, X3 ?$ F* D2 z
编写代码调用dll中的函数/ }/ N# y9 j* M% }3 H9 o
% Q1 R1 D" o9 T) u( h3 N* u1 [
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。6 A0 l$ q. T/ u: f* F) v* j

. I. c' n& ~$ q6 G下面是一段主函数的编写样例:
# f! N2 F* X9 o
. r; z5 U/ {' Y; A+ J. h! J// newdll.cpp : 定义控制台应用程序的入口点。
3 e/ o$ f8 O5 O7 [! Y4 J8 {4 C8 C- }+ z' y3 I
//# z3 T4 L; o) ?* H
9 R: \' v: b, A. A" O
#include "stdafx.h"' x" I/ }+ d0 Y

( N& o/ Y8 |/ D9 [2 S) Z#include
- C. v1 w6 s# a: O0 B# Q; `! y' T0 j' k7 U: s" |
#include "engine.h"
2 {' o  b4 i" ]! ~
9 s' I" V/ T1 k  M' J  f8 f#include "mclmcr.h"
; r3 Q0 |* y' `* S
( R3 D) H  H& y3 K6 `#include "mclcppclass.h"
. M- H; M, a, Z  x6 Q
1 U' H$ P6 n/ W#include "libMyAdd.h"
! T8 N- ]" m  P. J: c0 d  P: Z
- \% V" K1 @4 I1 }& z- pusing namespace std;$ p, J9 T- e0 L+ h  y4 t5 g

$ Y) h# }- A& U& h) S' d4 a$ E# fint _tmain(int argc, _TCHAR* argv[])
4 B5 \( |5 a# L" {) I3 o
" y! A6 e% J. w' H" W" R' m{
; p+ x* P& ~# e1 G, N/ a
$ W# E" D' f: Q. i3 F* z if(!libMyAddInitialize())
. ~( F6 ]* c1 _1 v8 C' d% @  D' i8 w4 y5 a" o. ]/ v
   {
/ A8 }2 _2 g5 |9 S0 x, ^8 k3 C% H4 ^* I
   //initilize failed!!!"<<std::endl;& @8 C" S+ F& r

# n# W' Y- p2 r' L  y% v$ D    std::cout<<"错误..."<<std::endl;1 A8 f  _, h7 c$ H  l. w

, |& h, V" U; o6 }- R, A6 ^   return -1;, ]. t" N: X8 F

  o1 f& m* \, \   }0 l. U( k+ y  }( H) E# v

6 H; g( U4 B2 i4 D0 ]: D0 e double a = 6;
! N: b+ `; e; J! C% F' L7 {) G* \! h0 L$ f, M3 \4 J" j
double b = 9;4 }/ N8 i, Z( a0 F) t. o" \
7 t) |  `. t- e5 {
double c;( B' |3 Z" j. D' p+ T
2 @/ l3 I: Z5 a8 N! _
mwArray mwA(1, 1, mxDOUBLE_CLASS);
+ N$ v1 e3 U0 @0 h+ }8 @; o- C1 S- r. D
mwArray mwB(1, 1, mxDOUBLE_CLASS);- q) m8 U" m( C8 N. c* O/ s- E
5 M( ^! L+ E6 t% i
mwArray mwC(1, 1, mxDOUBLE_CLASS);
( b7 E: z* t& M! ?3 I; u2 \
& L- X- V9 I0 D; p- V8 d! nmwA.SetData(&a, 1);
& T! u  t; d6 G
; L# c; \/ f2 u$ imwB.SetData(&b, 1);
1 @4 W, k. I1 ^- U, u
1 z' h% H# q1 }$ c* @1 U' [! [& d3 a6 pMyAdd(1, mwC, mwA, mwB);0 t1 i: A- y4 ~

* y6 u$ d( Z$ y  Pc = mwC.Get(1,1);6 G# Y  r/ g% r" o) _

/ M  `8 C6 b2 `# P. T" Hcout<<c<<endl;' D+ |  O5 C( {0 ]9 {0 q! T

7 o0 r1 Y+ y1 v: C$ t1 X0 ^$ Q% m* |! p, ksystem("PAUSE");
; |# ~8 d- M: X& K7 G% |2 d. Q" Z/ }" J7 ?7 b5 K, p3 _1 S: M
return 0;! L- {3 I5 Z  Q
  ?. B$ ~0 y$ Q
}
% z5 w1 M( l( K; \( K) B# [- B: p1 B; E9 T, M2 Z
这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。
/ d$ c* u, {: ~; J, n" l; C2 w( B! h; x: h: b, n# g5 [$ W5 D- _1 D
#include "engine.h"
% a: {( H; ?- X& I3 w8 D# D+ r; Q6 |
#include "mclmcr.h"% O( U. E, e% p) ?

& ^. W6 Z* r, S0 C4 O#include "mclcppclass.h"
8 t3 H5 l/ d) k5 W( O# o/ ~& r3 G) t( t
#include "libMyAdd.h"       这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)$ L4 F5 w& i: m# x
9 H% ]  O7 h$ t6 s1 Z4 z  ^
现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。  出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck  to you!2 h( n- f/ z3 M# t3 e7 E

- @! @' d0 A, M- H9 P7 `, e1 z备注:3 M) V* [- F6 r! U5 o
0 W8 p- G$ w4 ]
1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。
  @- C4 U$ Q7 z) e% J$ z2 a6 b) h4 r2 |3 l6 d) |
2.主函数代码中if(!libMyAddInitialize())是必须的。( g! n* T2 d+ ~

. V: N4 l# U9 `( B- }- V4 w7 m

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-31 22:04 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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