|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑
& V$ a+ i2 f1 t L9 z7 o- y3 w! ?& J# N5 ~
0 V8 t5 |6 t) C9 e) c
以下内容转载来的 部分亲测 部分未测试" x: q: P: X3 i" a
% ]! `) ^, j' x: p7 J! V0 d% j8 u3 C
8 G0 D7 i9 i% x% m
VB调用C DLL时的参数传递
' O7 }- r. f1 N7 L, T* i0 A2 u* f- D. S$ g* ^( e5 `* A1 N+ i' s0 h7 _
函数在C中的原型,参数类型和传递方式 对应关系
k7 E8 P* y1 M+ \' L, g
! s; J4 U- D, f$ x: l$ z% E5 i! R2 d7 l/ d) C( U q
3 G/ H+ v% Z# D
C DLL 原型 VB声明 VB调用: r2 x, Q! t) s1 Q& |
4 f+ |! ^' u. a( xUSHORT a ByVal a as long Call func(…,a,…)9 y) B$ ^/ [% k
4 [: b/ F1 c% n( p. c5 xint a ByVal a as long Call func(…,a,…)
9 t0 y! W) q: Y# Q6 U* q8 T) z2 |, N& K- r' F3 `8 L: O" p
long a ByRef a as long Call func(…,byval a,…)8 P5 @5 s* F: @
: @# @7 e* u( Z9 `% D& _& h J
int *pa ByRef pa as long Call func(…,pa,…)
' A: G, I R4 q" g! \) @ a8 f0 v4 a- g4 b8 v
long *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)
$ j7 a0 B- }* h7 W8 s
8 R: S( T! d& XLPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)
: ~& r0 `* x$ x& j6 n9 A
8 y: `. \0 ^( v! O$ D$ `5 @- K) Tchar *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)
+ U% Q2 B7 P! |4 C. b# v- u m8 e& k/ l) A5 s# b+ w: y% f
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)
$ g. N+ w) z6 |* D/ C+ Z- z! k7 |) c: e7 @# e0 l' U: K
struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3) 3 o' o3 d5 X* J# G. w4 x# `1 k" ~
4 a* C T1 w4 K, R
HANDLE h ByVal h as long Call func(…,h,…) <---------(4) * g6 Y. b! }, T
7 @# w. U1 C# ?. b
备注 2 { r0 f/ h7 }
6 z& T G4 x) j
1)不推荐使用此方式' @3 ~' Y4 N8 ~, c' O' g+ K
5 v# N" Z4 H; q0 J8 ^
2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 507 I% u6 k+ @+ ?7 Z9 j! t* i( K
: {1 x; Q2 E9 W R
3)用户定义子类型必须用ByRef方式传递,
; G( h$ n" k* A5 I% \/ o/ U
6 {# b. D& Y2 B; W! Y1 K% i4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。 4 `8 Y& M4 T! E4 c
9 P: Y3 G1 V) F% O; t, f% f7 H6 L. g( a" i, l
/ X4 n+ M' B6 F) p
3 f7 N4 N+ z t0 w' `. Z4 X, ]' J( A7 A3 @$ k# C3 Y( Z. v" B
1 l6 A5 F. s1 @/ F8 N
" A Y1 T0 S: B4 S+ W8 K数组传递 $ E. Q1 |9 y& a/ H7 H6 q
, S$ F# p s y
数组传递值用ByRef5 y( o% n2 o. ^/ ]- k
9 c% G5 y9 z- \, k/ J) Q- N# O VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。
" @2 W' U. g: X7 g4 o, S8 p. A
8 G9 ?+ T1 F' ]7 b+ M) e. u/ L# y) C
, Y# o. g1 _, B4 \; z
VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。3 ?# R: @2 a: Y6 d# M9 |8 K
, e8 m* M# d, i1 v
. `+ a( c' O/ r: L; s9 M1 H
( ]6 V$ s: N$ H$ y7 y
7 R/ M& h/ D0 B+ `2 J7 W
$ J) b/ c# b2 Pdll函数直接返回字符串7 I3 A. r: ^( g
6 _/ d9 h) j" Z5 b
0 W, B$ R! T+ P$ b3 b K
/ A! a+ R7 C2 Z
VB下的字符串格式和VC中的char有些不同的/ K9 Q+ z4 w0 f
6 P! }3 ^, l d0 J0 \ 直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子:
, f! @2 [8 T' T+ {' }0 ?/ r [ D& x! k5 v( E; E2 E# o" m
) N! Q: z) H ] i( e5 O& j
% j4 L# `8 g: l0 W
EXTERN_C BSTR WINAPI RetStr()
4 Z* r6 D+ G2 T6 i6 k6 p
) D1 L$ T9 R1 L1 q i" s8 i* ~ {
( y* ~( h: T2 h# T4 O! c+ t& j' a# b- s' ]8 R/ E
char *str = "1234567890";
. O. x9 m |# {5 Z v
( l" g+ e& Z) k! U' g+ m return SysAllocString((BSTR)str);
2 b5 u3 U$ q7 P+ L+ p2 ~: T4 T: U( B9 P h9 P1 W$ ^
} $ m, ^7 m) d/ a6 n
6 h, ~& S) {/ w% R& `7 q3 Y2 S4 T
或者参考一下VB下调用GeTComputerName的方法.
5 I8 C8 z% W) R, I! }$ h
1 }' K2 L8 ]5 b# H4 j2 j8 `+ v" u H5 L( d. w0 h
- E p% I& j4 ^& k7 H o) D
@, P1 x8 i* l# R- h
5 X( n9 h. n2 y* B$ n3 \ VC++与VB数据类型对应关系- X! X, V, x( d# ? j
7 Q* i# c. V% _5 U% B% kVC++ VB
$ p# T. e E3 }short Integer, E- ^" S0 e/ h
int Long
3 H2 M) K. Y: s9 b& W+ W# rlong Long
. \& h! L; \6 c& X5 a5 aUNIT Long8 `- }- P8 ~6 N7 ]7 u- J3 R! K/ }! D
ULONG Long
4 a2 O2 ^+ x$ `7 o0 iWORD DWORDLong; }% P) n2 \1 x# {, Y6 ~$ L
WPARAM LPARAMLong$ k6 A/ |% ?1 x1 c( M- |
WMSG UMSGLong- R8 u# a0 E7 f0 i
HRESULT Long
6 F+ t+ G+ a1 q3 y; [% D$ q$ Q( GBOOL Boolean% N+ X4 d1 S* N' P0 j, H5 W
COLORREF Long) [! f5 V4 }. f1 O3 y
HWND,HDC,HBRUSH,HKEY,等等 Long
1 m( r( I/ i8 }( ^LPSTR LPCSTRString
& Y J$ ?0 a6 HLPWSTR,OLECHARBSTR String
% S" p; x4 M7 u `) r. p& DLPTSTR String" ~ Z3 a+ h) n7 `" J$ ^
VARIANT_BOOL Boolean& e9 y& [/ N. ]. L
unsignedchar Byte- t; i0 A" F; t' l( M4 g" M3 r, ~
BYTE Byte
1 Q9 e. T7 ~, I& @8 N5 v, YVARIANTVariant3 X r) [! T; H; E
(任何以*或**结尾的数据类型) Long& B1 e5 D2 t& `, Z
5 s7 c1 R, J, g
6 r. k0 @1 n( i. q4 b$ wc中的数据类型 VB中的声明 结果/ ^( O; u& r# f! Y4 L
1 X' t9 F; W# M2 ]) C8 S! F, pATOM ByVal variable As Integer 结果为Integer 类型的表达式 + D6 u8 q! p0 ]
BOOL ByVal variable As Boolean 结果为 Long 类型的表达式 + w/ P1 W5 }% s: c9 m' h1 `7 C% R
BYTE ByVal variable As Byte 结果为 Byte 类型的表达式
# b+ P/ n( {8 YCHAR ByVal variable As Byte 结果为 Byte 类型的表达式 # q8 o: K6 E- a' i. J
COLORREF ByVal variable As Long 结果为 Long 类型的表达式
3 r" n) a3 W6 ?" J' L' U0 nDWORD ByVal variable As Long 结果为 Long 类型的表达式
. i; l: z# ~( P* Q, C* \HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄 3 F+ Y, p, Q; s4 I5 D/ Y; K. T
INT, UINT ByVal variable As Long 结果为 Long 类型的表达式
4 o& D% ]5 f! w+ a# a2 vLONG ByVal variable As Long 结果为 Long 类型的表达式 ( R1 s' M( d. M
LPARAM ByVal variable As Long 结果为 Long 类型的表达式
1 W" E# Y4 H+ o3 RLPDWORD variable As Long 结果为 Long 类型的表达式 1 C' z% L9 Y8 j( m8 j' n
LPINT, LPUINT variable As Long 结果为 Long 类型的表达式 - @: c6 X% V4 K6 r f1 ?* d3 X
LPRECT variable As type 自定义类型的任意变量 . \# U0 o' c; T' Z
LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式
7 r, d% n- Z" Z9 `# Y3 k/ zLPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
) I; T( I( t( n% pLPWORD variable As Integer 结果为Integer 类型的表达式 - J! n1 u' c' R% @# }4 P0 q
LRESULT ByVal variable As Long 结果为 Long 类型的表达式 4 D: I s7 c7 x6 P9 u
NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式 9 E" P8 U1 b: P3 x# u' l5 E, h
VOID Sub procedure 不可用 ) @* `% S( g% Z2 A; _
WORD ByVal variable As Integer 结果为Integer 类型的表达式
0 k! m4 X; I* ~3 ] sWPARAM ByVal variable As Long0 d( ^5 H- K% t" A! m
4 F, ^- b) }* S |
|