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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
matlab封装DLL动态链接库 再用VS2010调用(matlab VS混合编程)(转载) 9 m3 A4 y7 B. B
/ h( L# J8 e" Z2 K
整个配置调试过程使用的环境为matlab2011a(version 7.12.0.635),VS2010,操作系统是window7
' G: G) c) a+ A4 q$ b  H
4 G/ N0 E- C" D' C一,设置操作系统的环境变量。* ^# x  t  V  Z) w6 l; i$ `
6 Y7 G  f  K3 J' Q
系统变量增加D:\R2011a\bin\win32;D:\R2011a\bin和E:\Microsoft VisualStudio 10.0\VC\bin,这个分别是我的机器上matlab和VS安装目录下的路径。
, l4 d( o: F$ e, g+ P0 A1 w7 C9 {; Z* O- M
系统变量设置完毕后需要重新启动计算机方能生效。
# c: B8 z! ~! Y1 o
' G3 K/ z  i  N2 ~* h二,设置matlab的编译环境
, y& p+ ?: S9 ~2 I, {, E7 {, n1 o0 H+ ~8 |& ]
在matlab中输入命令mex -setup,选择Microsoft Visual C++ 20106 r3 F) L* N3 Q& O' t2 H

; v+ J: e( s  H  A. i% W再输入命令mbuild -setup 同样选择Microsoft Visual C++ 2010
6 x) d, L& [2 V2 M4 v7 y7 d7 j; n5 d# {5 _+ o
p.s. 这一步中,在我自己配置的过程中,matlab可以很容易的识别出机器上装有的编译器以及他们的安装路径,其中包括VS2010,选择它就是了。也许有的环境下matlab不一定能找出VS2010中的VC编译器,这个怎么解决就不知道了。+ a$ }7 E: c; m7 B9 a* Q- J
" }; ~* a/ M6 u2 a! [: A6 L
三,matlab编译.m文件/ G& M! X- f" k$ j- C
& A( h: ?# T1 Y; d- {. l
输入mcc -W cpplib:youRFunLib -T link:lib yourfun.m
; n3 `8 L( K0 t9 l$ M8 n% Y( c# z4 k. q
其中,yourfunLib是生成的DLL,Lib的前缀名字,也就是你最后可以是使用的DLL以及Lib库的名字;yourfun是你需要编译的.m函数。
& T" H+ y7 g) k" _
9 F* X$ g/ f) b( J/ N9 w编译完成后得到了下图中的一些文件:
* |" N) T; ]  P9 f# [, y# i% b5 i9 R6 F# ~$ m8 C
' q, y9 S* l" b$ W2 }' m1 {

; E3 O5 J' `# A7 f$ D- B* m9 j/ y% z这些文件中后缀为DLL,LIB,H的文件在VS调用的时候有用,其他文件目前没有使用。(这里我把yourfunLib指定为aetherLib了)0 A' I0 L5 c' A# P6 _9 r0 ~& W+ L  ?
5 L6 g% ?. o0 \# E6 V
四,VS2010 的配置
( C1 {( o' ?0 d7 `' a. a$ N; A: M, O, Y1 T
新建一个控制台项目。
* C3 [3 F9 ^9 A- ]
6 j- G" v" U( v( a9 d打开项目的属性页,针对这个项目做如下的设置:
& _! M6 g  b: V6 V  c: n2 z' u% j% }0 Y6 W; ]0 b; e
1.VC++目录下的包含目录添加) \/ z: {1 ^% i* {/ k7 b& ]3 O% l

+ ~& }7 l# ~1 lD:\R2011a\extern\include(matlab安装目录下的路径)
4 G% P7 Q* O: x" }  g# o# z; u$ o2 \$ J, W  \2 M0 M
D:\R2011a\extern\include\win32  (matlab安装目录下的路径,下同)5 r9 D1 [3 j& s  P7 c
9 ?- v. U* @8 ?9 q
C:\Users\lenovo\Desktop\aether\aether  (你自己新建的项目中的路径,下同)7 P- ]6 G" C  ?, P' |

9 e5 _8 [$ l# a/ [7 t3 D2.VC++目录下的库目录添加
- p0 ^- e- t" C8 l& Y% W3 w: x
, S/ A/ C0 L; o* G' x2 lD:\R2011a\bin\win32' A/ z+ U9 K) c6 Z3 x. P

7 E7 [2 }  v4 x' eD:\R2011a\extern\lib
$ ^6 c; I6 H6 S6 }
* q/ T2 n9 ]' d% Q' FC:\Users\lenovo\Desktop\aether\aether
. c( a! _: o4 C6 d3 W- @( \" Z& G2 d" {+ d3 E7 `
D:\R2011a\extern\lib\win64\microsoft- ]8 ~" S( |: L8 [+ N1 I% i1 Q

. f+ n5 A( y0 k4 ?; @: K& JD:\R2011a\extern\lib\win32\lcc
5 A: U+ l) D1 Q- B0 i% A! ?! L+ P& \
6 S0 G  u) h* ?, Y% h! B# T; s( lD:\R2011a\extern\lib\win32\microsoft
7 V+ Q/ e0 @* L3 V* Y7 R' r, o  O4 ]/ ~( W5 [. H6 y# [
3.c/c++中的常规里面的附加包含目录添加. x' v3 W  L& x  ]4 e+ ]  z

& Q& a/ k# c% lD:\R2011a\extern\include
9 _" `' z+ Y7 m) P# B8 F( P
; o5 \9 b  L6 b9 V4.连接器下面的常规中的附加库目录添加
" Y* l# u7 u' [" T" k& q! \& t1 r9 w/ T3 `4 f8 a
D:\R2011a\extern\lib\win32\microsoft
2 U4 l" \- l; U; [6 _% a# I3 C4 x" n5 W0 U
5.连接器下面的输入中的附加依赖项添加3 z( l% y( ~2 \/ }$ d2 L

3 |9 X9 m0 G$ c. W5 m  z8 R$ tlibeng.lib
; M1 o) |! u. R* P
/ a  \+ b7 y1 U1 Y( f; Ulibmat.lib
; B. B0 F4 S; b' w5 Z) b) J
# j7 Q" l0 t# ]0 f: }$ @! a) Tlibmex.lib9 ^& c6 C* c0 w' a

6 ?7 L$ @& m- a9 c8 z6 X3 d. _libmx.lib2 @( [- y: r% }: m6 F1 B2 g

5 _# @, ~, i9 W5 Kmclmcrrt.lib* p0 `- V5 w4 a9 C" U' T

8 ?2 g' X+ F2 z1 `9 Smclmcr.lib+ t/ T+ a6 `: i: S5 [

7 \7 I" F" `5 `2 ?6 qaetherLib.lib(这个是你自己用matlab生成的lib,前面的是matlab自身计算引擎中的lib)( E) Y# H. o) M$ E0 P

% _4 `$ Y8 p; M: F( R* a" `在解决方案资源管理其中的头文件和资源文件中添加文件
* D! m  _( L! D- ^( a8 Y. J. D1 R. z; ?( ~9 j$ a
1.在头文件中添加生成的.h文件
7 M. |; Q$ O5 v. I! P. U; @
6 e+ }; d" y8 Z$ e2.在资源文件中添加.lib,.dll文件
, @7 J  U; i/ z6 A
8 D& \* ~7 k8 n; L3 n3 S+ j5 R3.然后 把.h,.lib,.dll文件拷到你新建的项目的目录下。比如我把他们放到了C:\Users\lenovo\Desktop\aether\aether里面。/ Q! x$ {6 g# s1 C: c

8 ~4 @+ d. K8 g4 M& ](最好是用这个命令进行编译 mcc -W cpplib:MyAddLib -T link:lib MyAdd.m -C
; d9 Z7 p6 U( U2 c- z% y7 Q
; S. j+ a: U# j然后把.ctf文件也拷过去。)  k- S/ D6 [7 U8 p
2 p$ @% Q. \# Z2 m
编写代码调用dll中的函数
! |! G* @3 k$ N0 E( Y0 C4 e3 ?% v; k/ Z1 w% Q7 R- |/ X+ i  {
dll中的函数的接口形式在.h文件的最后面给出了,你可以去翻看他接口形式。这里面的函数的输入输出参数都得是mwArray对象的常引用,关于这个类请读者自己去网上搜索资料。你需要搞明白的是mwArray是matlab公司专门针对“c++调用matlab生成的dll“而设计的类,因为你包含了matlab安装目录下的这些类,所以你可以在VS里使用它们。6 J" O7 A3 y2 s- r3 L- m3 ^
3 z# z8 L6 x9 q5 k# d
下面是一段主函数的编写样例:
5 Q, J( O, I3 ^3 V& e/ p( M) u3 j$ x1 _3 `. n; M  Y
// newdll.cpp : 定义控制台应用程序的入口点。
% T5 c% n3 k  x. C' s* t! ^8 X$ }2 b- z. {6 Q
//' u4 B) v, u+ n' ]7 q

* `' @& K3 c" A( p9 e' D#include "stdafx.h"' S5 c) s/ y/ a/ i0 @
+ T. z5 W# ?' [! H! g
#include& U: T+ y  h1 t8 O, U

* j2 a9 Q. [) \# q% Q3 \/ t/ Q#include "engine.h": A) b. v! a3 u, s+ }

+ d) U; N# j- E#include "mclmcr.h"7 [* t& v9 C6 T3 A3 z
- T! \* ~3 W: q6 M5 g0 j
#include "mclcppclass.h": S; {, K4 U: Q. ^. z

3 T5 q/ O5 T3 u5 L+ |#include "libMyAdd.h"! m. b5 G& `9 o  Q0 @" |
2 U: o! l% _9 w. f: u, _
using namespace std;
: d4 [1 _2 u  g# j+ u. s5 g+ k* W, H0 p1 I" {4 _
int _tmain(int argc, _TCHAR* argv[]). _  B! X' F( k: u

" D7 l$ E: D: O  z{
/ H/ s# {0 z& G$ {% z/ U
  e% U, ~$ U$ `1 z if(!libMyAddInitialize())
9 w" F3 v" C) H- Z) v2 ]/ X/ R$ y8 I" m
   {
9 r$ A; m/ U; m: I2 z8 B
! `7 W$ A2 e( S   //initilize failed!!!"<<std::endl;, Q" K. L/ B2 {; M5 }$ t

/ ^: o8 Y+ n) b% r3 Z5 ^    std::cout<<"错误..."<<std::endl;* T& [8 _# E5 W" f  x3 f

7 d& t- I" s* ^   return -1;
- A& y% {# x% T6 P+ b! T) @8 K* W2 W4 _9 s1 a
   }
" [& g" ~( ~) d. Z) E' P# O% Q* T+ J( {7 g9 w6 D5 z7 m% @
double a = 6;
  k, R- n  B; F% c5 D/ G" G. ~2 ^
8 b: B9 A/ N5 I9 m7 f8 e" Q% \& sdouble b = 9;
: B4 c2 q, t0 Z0 z3 n9 C
% O! i# p8 N9 k# J- ]' I$ _double c;# N3 }, l2 W4 W8 b5 Z

2 ~: w7 f# Q4 H# R2 c! r5 @6 X! O2 emwArray mwA(1, 1, mxDOUBLE_CLASS);9 [( @% |; W6 L/ T5 Z" T( I% x6 S8 d. |
2 d+ G. p  P& Z- S8 `2 w
mwArray mwB(1, 1, mxDOUBLE_CLASS);3 h7 S" R0 V5 W+ O% k. e: p

( p% j2 s! D6 T# C; Z9 qmwArray mwC(1, 1, mxDOUBLE_CLASS);0 d  H/ N" ?: U! v+ j
; [' {8 u- F5 _
mwA.SetData(&a, 1);
+ T1 P4 B& \- e5 Y: N7 y) l7 b
# X$ m3 H) l7 T+ B. omwB.SetData(&b, 1);8 ^- T9 Q7 ~0 B  g( b
0 @- G+ F0 e; ~
MyAdd(1, mwC, mwA, mwB);7 {* j' W' N2 e( D* i& N# c8 p

% P$ H# ]$ u% ?7 E/ gc = mwC.Get(1,1);
  A- L2 B1 }' H: t+ [; _9 ?6 F2 I# Z
cout<<c<<endl;( k! L+ q; l" h* v+ J+ s5 i: A8 Q

1 e/ L+ o! Q& r% a  X$ C% dsystem("PAUSE");
" T# u* E8 W6 _' B0 m. a# I' G4 Y7 U, H: o
return 0;/ f  z' c6 A' R  {% b+ y
$ T9 a9 Q, g* ]0 r$ y3 h7 h6 L
}
, }! f$ P( k. L& F. n/ J
, H2 \% I9 l% M3 s3 q2 ?这个dll中的函数只是实现了一个简单的两数相加的功能,是我做基本配置是使用的。5 {0 M2 u- {5 G; m$ m" [
  h5 P' ~% I$ N2 N8 F) C
#include "engine.h"
) l+ H) Z& Y  X! a7 O1 |4 s% l- v0 s0 ~
#include "mclmcr.h"! {3 I+ w1 g: g
9 _6 O" ~- H2 U) O: u
#include "mclcppclass.h"# `/ u$ T9 S/ O# S% a6 c4 D$ v

: d9 X+ q9 i% B8 y+ N1 S#include "libMyAdd.h"       这些头文件是必须包含的,其中engine好像是包含了matlab计算引擎中的所有dll(还没有认真考证)% a' T" M+ V& i; j' w* A4 e8 j

* ]2 X  @8 Y: F' L' d) c3 \! d现在,运气好的话你应该能看到你预想中的输出了。如果出现了问题,比如找不到路径,不可访问等等各种错误,那只能你自己去解决了,我搞了整整3天,上面提到的错误都有遇到。  出了错误你可以尝试去百度搜索其他博客,更好的是去google用英文搜索相关的问题,一些社区里面也许有答案呢,matlab版主文档我倒是没仔细看,也许上面也有不错的帮助呢! good luck  to you!
3 p" J' `3 x8 H7 L
% F+ H; X! X# M  p备注:
# M5 F, B6 g/ K$ K
% T# E) ?: B/ k' P) X) x# R2 F1.我自己在搞的时候,遇到的问题是.m函数中本身就使用了c++语言编写的dll,然后再封装这个.m函数。这种情况下你得保证VS可以访问到你用到的那些用C++书写的dll。但是只要用mcc命令编译.m函数后,你在连接器下面的输入中的附加依赖项中只需添加.m 生成的dll函数就可以了,不需要添加那些c++代码生成的dll。这里建议你把matlab项目拷到VS项目中,直接在Vs项目中工作进行MCC编译。
" y7 o+ r& \; \$ K
6 ]9 I! b% ]- n/ N% J8 e4 b 2.主函数代码中if(!libMyAddInitialize())是必须的。
. k0 `/ Y, v# A6 k3 Z' H8 s! g, c* b2 h9 ~: N* w

该用户从未签到

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

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

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

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