|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑 % |1 d, {5 m- u
4 }6 z7 e8 `6 b+ ^& z& e
& R7 O+ u& M& `& q+ N以下内容转载来的 部分亲测 部分未测试
$ F; Y3 g( u& w$ n; @$ n
T; ]# D: t8 p
: f* U3 D3 M2 N! {& d& R# v* S; G+ F
VB调用C DLL时的参数传递
. t+ N" A! c x8 S- B; p' A
( q+ F L0 n5 ]& _; w: F函数在C中的原型,参数类型和传递方式 对应关系
" E' h; H9 k4 |
8 V/ m! l( Z) q' Q4 A
$ W [; n* g5 j- }
$ l. t* L3 t& i) n% [C DLL 原型 VB声明 VB调用
# |7 Q; ~! J/ |
h0 I& a6 j" M UUSHORT a ByVal a as long Call func(…,a,…)
6 V) j4 b2 o# [$ P1 v- C- K% Q; Z) }: B3 s% F9 k% F& H
int a ByVal a as long Call func(…,a,…)
/ u4 F2 z4 h, Y' h9 O
: w0 _0 V! G7 p, R% v2 C" L% ~long a ByRef a as long Call func(…,byval a,…)- ^- i% _' o8 J# I5 C
! ?% S! Q0 X6 ^int *pa ByRef pa as long Call func(…,pa,…)% o5 T0 j, x9 A
( p) a+ `8 \+ `1 ?7 o
long *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)
% u Q) c1 R+ W& O& ]) N8 C& A9 ~. G: p0 P; Y6 r/ { m
LPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)& D: p" p) Q* s, C o6 v P$ ~& ~
9 O0 ~5 Z3 |1 o* G" Qchar *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)/ q. C6 s8 u. G8 c9 ?0 F* G
* W, l/ V% ?8 h R% J5 B
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…). S0 F" X0 ~) J3 p/ O1 C
w! l' Q( \0 J# P0 ~
struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3) ! {. u) @ J* |1 R8 X( O' U
/ D; b! s7 Q1 d( n0 E) D9 sHANDLE h ByVal h as long Call func(…,h,…) <---------(4) & ?( j4 {& _% e8 B3 J# I& z6 k7 {, v
- M/ j- d& |: X7 |# c7 t
备注 ' W. N4 W. e/ ^
1 ^ n$ L: L0 |% v$ p7 Z3 \4 B b1)不推荐使用此方式
. y& p' m$ ~& V$ H- C" C
$ h4 I, V8 X8 |, p6 \2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 50( w& P, a& Y, V, i: e
/ l. y. I8 P' M Y+ F
3)用户定义子类型必须用ByRef方式传递,
0 e# e* N. }& @& F: [" w4 X; V) S9 _
8 H7 V7 z" p& Z5 G4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。 : p+ S8 ?" S; Y, a5 ]* E
( E" A) k3 W Y
- ~0 E. a3 h2 w3 j/ D; b3 R
3 T; f2 _/ s R d* X' ~8 z4 \) L
( P7 r$ a7 [, g6 p+ i
3 x1 ?$ Q( H" ^6 J8 Z7 ^
; j( ]6 A* @7 N( ^
0 A" D/ B. ~) x5 W+ ]数组传递
5 P9 u8 M. V& K5 u g; c3 p- x, f/ @. O
数组传递值用ByRef1 H! w, {' g4 D; z( a, I% \
, X4 p/ h9 z3 U2 k/ _& u% G; |
VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。
$ B. O: Q/ ~ v# V0 b, t1 |4 M3 h% k/ @4 C1 n' g8 h
1 I* o2 T6 M1 q" q' ^8 _, X+ f( `0 S5 p. a
VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。) D6 o3 S. Q6 o" l
4 k9 @4 t8 W! f) k( c* m* ~/ R' \3 O' l% o8 u
! }) _: U# Y: J2 N, G8 {& w
; M! w3 t+ }* T. R4 b
' O. q* C/ G2 |, C f% a2 }& R
dll函数直接返回字符串: q: X; k! v. g
+ X- E& Z5 d) N6 V/ c
' j6 ^0 Z7 I( G; Y( a
; b. U& g* O) }' _/ m$ R VB下的字符串格式和VC中的char有些不同的" o" m2 C( I4 g S/ S
8 j% F {( x& @7 W& F6 b- @5 `+ B$ Q 直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子: 4 n0 k9 L: R* w
5 z5 p X2 s; E: |% V, j
: e! o9 S! Q. [
- n; M) G9 U0 p j9 m
EXTERN_C BSTR WINAPI RetStr() a* G$ |' V( V
$ d3 a: A2 _1 C+ H. f& b
{ ( I& R0 E+ i% o
9 P* Y& b" w8 ~0 Q% V `
char *str = "1234567890"; * S X7 R8 o% B2 ~
& ?! O0 M/ Y! X, i) u D/ l4 i return SysAllocString((BSTR)str);
' E, O. V* Z" N+ F' M) H3 d1 p( M& e# Q6 G) w. l3 i
} $ x4 b* j( h( X$ X) n6 ]3 |
/ @( r: z% d0 C: K3 v( h或者参考一下VB下调用GeTComputerName的方法.
5 V6 I0 ?: t7 d* Q! k
; l* o+ o7 P; i) W2 Q( C4 v7 G# a! G7 B. Y
3 V* }' M. y, v4 Z v* P% `5 c& f( C, p {* x( @9 {
' C* ]/ _ R! w7 @4 d. m8 k- Y; z
VC++与VB数据类型对应关系
) T3 g0 w; q* H% T! C' N# Z5 m7 _6 K& Z
VC++ VB
* m B5 N( n9 Z8 a( eshort Integer' I0 `% X$ w/ h
int Long
' C; t; T3 N. @* c0 }long Long
2 _' l! M( t# N$ a, ?UNIT Long
- r Q0 s- _6 z0 V/ G* ]1 w+ kULONG Long
6 F3 `/ V! x! K# N$ x& Q& d/ m6 Y$ EWORD DWORDLong
8 ]( G( j J5 R8 y# p! OWPARAM LPARAMLong
2 j% k0 \ H0 e- z; l9 GWMSG UMSGLong) ~- D' i4 E* m3 m4 x
HRESULT Long& D: ?: O9 L& @
BOOL Boolean
! X" \* x3 a+ J) nCOLORREF Long' A/ _1 t) N) t
HWND,HDC,HBRUSH,HKEY,等等 Long
) B T) V4 E) H2 ]# f4 C- LLPSTR LPCSTRString
' `( P% ]( g0 e: P9 ?, Q! [3 {LPWSTR,OLECHARBSTR String* e0 u9 y9 Q$ v9 Z2 H& Q% g
LPTSTR String
% y* D% h2 V+ SVARIANT_BOOL Boolean4 m$ z, e$ H( e3 s
unsignedchar Byte6 w Q5 I% C1 D+ H9 ^! e4 L
BYTE Byte8 m! {/ Q9 _6 m$ }- _9 l7 D
VARIANTVariant
9 k( Q4 x1 N- L4 X. [, \: `(任何以*或**结尾的数据类型) Long" j6 Z/ Z: U, z
- T1 `, B9 U8 W
! L7 E1 _$ S t- V
c中的数据类型 VB中的声明 结果
% V1 y2 S9 ]) F5 Y5 b$ u/ g& ?
7 I& @0 ?* u1 q! a5 uATOM ByVal variable As Integer 结果为Integer 类型的表达式 ( @! k, P2 d! [# f" u( B H5 E
BOOL ByVal variable As Boolean 结果为 Long 类型的表达式
) j+ R) u6 H$ B: jBYTE ByVal variable As Byte 结果为 Byte 类型的表达式
6 }6 j- l8 \, D% t5 w3 Z6 }CHAR ByVal variable As Byte 结果为 Byte 类型的表达式
& M" r% a5 e2 ^* _. vCOLORREF ByVal variable As Long 结果为 Long 类型的表达式
3 `$ {0 f$ f" x# v% ^DWORD ByVal variable As Long 结果为 Long 类型的表达式 : U @# e/ {' i, r9 C! S1 B
HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄
. L! d) k' a: y, W" [3 e Z/ sINT, UINT ByVal variable As Long 结果为 Long 类型的表达式 8 `6 o5 e6 j6 L+ ?5 m1 \7 {
LONG ByVal variable As Long 结果为 Long 类型的表达式
3 Q0 D) ?9 Y1 E: {7 x$ E+ XLPARAM ByVal variable As Long 结果为 Long 类型的表达式 # O2 K$ w. t$ ~. Y9 q$ {: F5 J( e" S7 n
LPDWORD variable As Long 结果为 Long 类型的表达式 - q! }, V1 M; a; i8 _0 p% D
LPINT, LPUINT variable As Long 结果为 Long 类型的表达式 8 g4 Q3 T# b ~5 U6 Y k+ r r) g
LPRECT variable As type 自定义类型的任意变量
3 m! z. c+ E- K2 ]; N, HLPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式 , b l+ w7 N- k
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
3 d, ]+ h5 e& M, O Q4 @* n# SLPWORD variable As Integer 结果为Integer 类型的表达式
* ^" S, |9 u P) m" G- G3 K. C( r8 QLRESULT ByVal variable As Long 结果为 Long 类型的表达式 2 q+ _* g' }1 ^! r* _* J. T
NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式 , [$ U. m) {! E$ H: ~8 n
VOID Sub procedure 不可用
' Y) n0 l+ N3 O, UWORD ByVal variable As Integer 结果为Integer 类型的表达式
8 j8 ^2 k3 v* c* e1 w9 f3 w3 X) p' S' M xWPARAM ByVal variable As Long
/ O6 y5 m( l+ {1 }- Y( h
3 g3 G$ O, N0 A6 b |
|