|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑 1 j6 k5 g% S9 \4 d4 l
' S+ y+ }* l( i7 z! \6 e
, @0 g4 a o$ }4 m+ R6 p) ?; _以下内容转载来的 部分亲测 部分未测试
1 R8 F3 L1 j k. x9 \$ Z+ K
, a% K" i8 G- t( Y0 _- l
( Y1 B4 ]: H) |6 |; @, c/ b) [2 `) k; T7 s% {& x
VB调用C DLL时的参数传递0 \7 ?* N( |) w4 b
0 e$ @3 [- j0 V) ?5 y7 }7 b& _
函数在C中的原型,参数类型和传递方式 对应关系 + q1 `8 H: r- V% g! J" x
' r4 x& P( u% \; L9 p1 n) E
6 i+ N0 q( z) t. b/ f
! l+ i+ _6 e) D# jC DLL 原型 VB声明 VB调用
! H9 Z, b7 J* b3 G h2 K' T* r$ i8 j: ~0 s. Y# D
USHORT a ByVal a as long Call func(…,a,…)& Z" a" `! @) s( |, |9 J, R* u
+ y9 L$ C+ }5 g1 P; T ?
int a ByVal a as long Call func(…,a,…)
6 a M0 p6 D4 n. C- G6 r; I% A( ~% s7 @" d" ~9 e( N
long a ByRef a as long Call func(…,byval a,…)
# o3 I$ R$ H) f. B! ]) G- B
' p, c8 x0 L+ O/ Lint *pa ByRef pa as long Call func(…,pa,…)
9 Q3 ~* {: R$ ~/ m
s7 Q. H( \ t! _long *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)
" V# p7 ^2 ~+ J& q! i! J; G9 j4 |& |$ y- C
LPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…) O2 [& j/ O- ]6 L2 x
3 J3 x* p G4 h( Wchar *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)' X' I- p$ S* V9 Z. t
+ a3 C3 C+ @6 O+ P4 @wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)
) H. } y* }. o: `& ?
0 q* P& Y6 t# u" M6 @struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3)
1 _8 u: P7 T+ h% m& L5 m* @( I2 I! B% X; x4 [" N. {
HANDLE h ByVal h as long Call func(…,h,…) <---------(4)
4 S* R7 I- k c0 r# f# `$ V
/ o3 [5 P9 C$ p7 c9 A/ N" @备注 : _) q8 F! i* M, F
( p2 L6 x% E: ]6 V5 H1)不推荐使用此方式
4 O" f. t+ ^7 z; I ^$ q4 z0 i- u# U' r
2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 505 W0 ^+ J+ Z, D+ t5 v& W/ T8 V
% M- `, y4 J- J3)用户定义子类型必须用ByRef方式传递,
' C# [- |( ?& ]4 {7 ^- t I9 m1 ~/ d5 T, Y
4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。 + R" y" e: `. x) H0 X7 D2 X$ Q
: O/ y7 I* W" K% ]
& h+ l* N0 D% U# t0 x
. Q) a/ B9 r9 B
! C% Z& S' K3 p$ O$ @4 y2 q" }2 H" d5 K9 K+ O/ O2 U' ]' M
& b- |" }% c- t/ t' d
1 R U' T$ a/ y, k数组传递
1 H; E9 ~7 Q2 w$ J
( M# L: y1 r5 y2 e" d/ f' N 数组传递值用ByRef
2 G2 M, u- r- A' N$ V% Y2 l. E0 x6 e
VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。+ K7 _$ D4 g' X
4 {4 V& N! \" y& ]
' p) k, C- o2 E" b {( @# M8 P0 |- a7 @2 b4 L
VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。* @5 @% B/ c: {5 ^0 ?* F' |
. _* }4 N b' x% @" J" }" P$ C) P$ m% z) f3 r
2 R# _# z6 c; S6 _" ~
9 j4 g( S" h) o7 @# {6 X
9 N% _0 P* n4 u5 R3 n4 b& m$ p5 B' ~
dll函数直接返回字符串
: g0 _' M% P9 I5 i. T- k$ G8 J6 r% K' _5 U) v9 d6 D
# S0 E3 }/ e; p9 k) y. Z4 l" m* n; ?+ j$ ?/ @
VB下的字符串格式和VC中的char有些不同的
# S# s# _! {1 k- p2 ?
& d5 d; { G1 o1 I9 b! e' y( e3 } 直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子: + `0 X; m0 u3 @0 x' H
6 Y" Y& L5 b, J1 r( k# W
8 f$ x2 O3 B# ?+ u' j+ I
1 A' s$ r- u' D
EXTERN_C BSTR WINAPI RetStr() ) g0 m8 E1 z8 @+ c9 Z/ f
. }8 L; U+ N! O% p9 e9 b
{
) G( T7 g. g p+ f% {5 e: ^
; ], o2 d9 r* E: U char *str = "1234567890"; ) Q/ O! C" a" P
2 V) U, F1 N, W
return SysAllocString((BSTR)str);
a/ m; A4 D3 n" n0 T$ X/ \/ n, K4 H0 X; c5 W* U% ^1 e6 R2 M
}
# E' I E7 F4 {+ F# c5 G! ?5 j. W3 r) Q, N4 T( @
或者参考一下VB下调用GeTComputerName的方法., ^: f) T, I9 |) S1 X
5 _- h. t& H3 C2 s; y7 W$ N
; R K# c; \' ^, I- A- ^; B! S0 z4 N6 A
6 q8 }+ M! ^! Z! I- A
. q6 Z" P. M" ] VC++与VB数据类型对应关系. M2 Z" T0 z* u% S4 C
: ~1 ^& z0 n" R. d; k
VC++ VB" _3 H4 [! h" a7 \9 H
short Integer( I. Z/ k* B8 }" h0 ]
int Long4 w) M* K6 j. X' P# i0 X/ k
long Long
- x, w- g) m3 y, t; R1 c- vUNIT Long; ]- ]1 Z! W5 z7 K! Y9 p
ULONG Long1 O& s2 k, Q. Q' K6 S* ?
WORD DWORDLong$ l% x$ A, ~; ^) n% b. V
WPARAM LPARAMLong
( L9 X- M! K+ ^) l/ b oWMSG UMSGLong0 }% |9 O/ O* U1 y# h3 K
HRESULT Long' C `. ?2 S j+ w8 ^
BOOL Boolean) w1 B$ R" H+ E; `0 H
COLORREF Long
. G: r. Y$ p) S- Q4 w% HHWND,HDC,HBRUSH,HKEY,等等 Long0 r3 F0 i# ]$ J. @. q+ f( T
LPSTR LPCSTRString, i# \9 }' E+ t3 A! [
LPWSTR,OLECHARBSTR String
8 R0 D& H$ c8 Z2 i5 ELPTSTR String
4 s8 s1 b$ b4 H: iVARIANT_BOOL Boolean
8 }: z9 U* y( O/ [2 D9 {: [9 Nunsignedchar Byte
' B- p' y4 \, n2 x# s7 Z% [. QBYTE Byte
- u* {3 @0 c& w4 O6 i# w9 M* }VARIANTVariant1 U9 d$ J) v n3 W. \* k. l
(任何以*或**结尾的数据类型) Long& U# @' _$ i0 I% H# u
2 }1 c3 k/ [$ T+ u4 _$ ?- V4 [
& i5 d3 a1 R4 l- c+ o4 xc中的数据类型 VB中的声明 结果
/ D3 \! O0 t; T- o& s T" x( ~, \
, a4 V7 C% p+ {$ b3 `$ X- AATOM ByVal variable As Integer 结果为Integer 类型的表达式 / k0 J7 u& s4 z( J
BOOL ByVal variable As Boolean 结果为 Long 类型的表达式
. S" P* {% O$ ^1 l4 YBYTE ByVal variable As Byte 结果为 Byte 类型的表达式
% X! O' v) r0 s) O& t( o! xCHAR ByVal variable As Byte 结果为 Byte 类型的表达式
$ @4 [0 z. c6 W$ Y- g8 {" [COLORREF ByVal variable As Long 结果为 Long 类型的表达式
' I1 I N) P: k' b" t0 QDWORD ByVal variable As Long 结果为 Long 类型的表达式 ( O+ w# S- m9 {
HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄
3 w3 Q$ C) n, Q/ R/ ?8 G, ]INT, UINT ByVal variable As Long 结果为 Long 类型的表达式
; z( Q) f, p) _3 qLONG ByVal variable As Long 结果为 Long 类型的表达式
* y3 [" Q8 S" v' tLPARAM ByVal variable As Long 结果为 Long 类型的表达式
# _$ u2 M- `) Z' R; ALPDWORD variable As Long 结果为 Long 类型的表达式 % D! U( q6 M Z6 u m3 l4 `2 W! B
LPINT, LPUINT variable As Long 结果为 Long 类型的表达式 ( A/ P5 d4 t" N: w! ?& _- S9 K- D
LPRECT variable As type 自定义类型的任意变量
- g8 p; k1 z% S2 l5 SLPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式 0 ]% @( S! G- S3 w0 Q1 |5 k
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal) ) r0 K3 ]: G( X1 C
LPWORD variable As Integer 结果为Integer 类型的表达式 - [: \ u m) ]( Y! n# ~! r5 B
LRESULT ByVal variable As Long 结果为 Long 类型的表达式
5 z8 J8 @1 L% R0 t1 b! S. eNULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式
6 h) U5 a! }8 @; ]! m5 PVOID Sub procedure 不可用 * t7 O, K8 S+ x! c8 ` `3 w
WORD ByVal variable As Integer 结果为Integer 类型的表达式
. h* B2 | y/ mWPARAM ByVal variable As Long' i4 |) y5 T$ a. i+ g- a$ V
; U0 {, ?; z' J3 H k |
|