|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑 , Y4 J' M) P: d% ]8 F @8 U
6 |+ m4 ?0 |- S; @. F! p- C w2 E; s
) n( M' u5 ?7 q" [/ F, c# m9 }0 y
以下内容转载来的 部分亲测 部分未测试: i+ b/ o O N2 W5 b; n: w; B
: u" W6 y- W O6 p- P# v
5 M3 P Z: r+ Q3 s! V% x# j- P0 c8 W- b/ a1 |6 C
VB调用C DLL时的参数传递& F" _: Z( {( N: `" s
P' ?2 H( L2 J; Y+ ^+ R* l: J! _
函数在C中的原型,参数类型和传递方式 对应关系
* S* e0 v: @/ @" ~5 Q' `' T# S. m6 u
, o3 V) z! D0 x' x! v" r/ Q. h$ S/ V9 n
C DLL 原型 VB声明 VB调用
* h- y; V6 |4 C \; y# \3 f2 \% f y
USHORT a ByVal a as long Call func(…,a,…)- B# \+ n" q6 ?4 ]) p
: l# C, a5 M7 ~" v: rint a ByVal a as long Call func(…,a,…) N+ I, P" d4 k% f- H
0 ]( \* L6 t s$ X9 ?long a ByRef a as long Call func(…,byval a,…)
) G5 l/ @& q# A8 u0 w/ q, Z' \3 [: W6 w1 I
int *pa ByRef pa as long Call func(…,pa,…)
; i. U1 Z: n t: i6 W
/ Z' F* }, W6 m# M% R& M% k- Ylong *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)
/ i" o, h9 f) r- W
U% }3 |2 L1 c7 w BLPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)7 Z% P0 r G, u# z3 P ?5 B
) R. }6 X* a( B+ s; `) b+ U" F
char *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2). E! U$ {1 }* x9 z% X, R
4 Z5 E0 [& f/ P) U( B' L
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)& P7 w7 k. U4 \4 p* v8 G" E9 l
) o5 B$ K- i# T; B1 Ustruct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3) 2 J8 ^: G8 d) n4 P, o
. N W/ n* v7 P! x; n' X
HANDLE h ByVal h as long Call func(…,h,…) <---------(4) + W" f- [) f: i
( m& R# x# Y$ n2 E8 o0 ]备注
a/ E9 z7 t0 }$ E. Y. @/ {# o7 B# h! i" \2 j( ^; k
1)不推荐使用此方式
# K; Q3 r+ i/ K# r' G9 W
" [+ x" `: S3 r. n3 U4 i2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 507 C2 z* X$ Z6 T
7 [: B7 Y0 @$ m6 b3)用户定义子类型必须用ByRef方式传递,
% `6 ~5 Z( D- A: O2 H
% a! J0 q% L Y0 U) d4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。
, z0 k0 E5 R7 y+ s& N& e* u5 L4 Z' Z7 Q- w8 R7 N& R( g! {2 n. g
, S$ B+ [; m3 P K: w/ k9 e
8 O" F5 @* L! G. W
1 Y2 E7 ]5 S. y" s+ }; A- C# }
1 ]! b% O; G9 ?( E! k% \
# H5 ?' `# E! u$ s" O' b
$ W* n' O( C! U7 ]6 }数组传递 ( {4 y/ W* ~! B- z X2 L; ~
9 i$ P3 P9 x1 n: R( k 数组传递值用ByRef0 z7 K$ v4 f, \2 }3 r+ n
: x( N/ W/ g5 T* O" y1 I' O9 H
VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。
0 G3 @& V) o' r, D9 m# q
% [+ H) ~ U( \( f1 Y J+ A3 { b: w* a0 R7 F
9 {7 A ^, o9 w8 z7 G1 S* ? VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。
# Q C5 n6 `/ u$ h" o9 w; q# Z6 u- @2 x! {& _
! l7 R {) X# _. p3 l1 A* u5 v+ [# S# q1 W# n
! M) z+ Q& B3 q4 l# v+ \" y1 y. T+ T; \6 R5 o
dll函数直接返回字符串7 p: t4 M3 ?( Q6 v8 _
& x! H2 u$ `4 B& M: s7 _" M$ F! b" H& a* J$ k; D
+ _ u" W, e8 d4 Q4 ~! K VB下的字符串格式和VC中的char有些不同的0 @: o* N2 ~# H1 Q2 D2 O
, T0 u) ?6 T1 d, u8 U/ u H
直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子:
, W7 I0 I. E, t
+ e' a o9 h8 Z
8 P1 h5 p7 F2 y" H, w% ?/ ^3 @. _* N5 i# K/ I2 O
EXTERN_C BSTR WINAPI RetStr()
# j* J: O4 R; ^0 w) a$ a
s. Q* Z) E0 K { # a" f: T/ L' ~) X
" S. m d8 V& S char *str = "1234567890"; 7 `0 }: u Y- m/ K+ V1 Y, l
! B6 l9 S! c) ^# A" ?+ ^
return SysAllocString((BSTR)str);4 |4 L8 K+ h+ Z$ R- G4 G4 _
5 [8 T8 e/ c' z- b: [) { }
/ J) U+ h5 _$ D6 w" i- Q+ ~3 |4 l% h# y" X
或者参考一下VB下调用GeTComputerName的方法.) f0 A. W- G6 d: j3 d6 @5 s, i
' ?4 p+ |7 c( k! v1 ~ i, k" o
0 U) }2 G, Q: o7 O; t
6 C1 d# {( j; \' A4 q8 T* J6 @8 c0 a% v3 x5 L9 o
5 K8 B2 Z0 s- `4 N! g! Q
VC++与VB数据类型对应关系
: C0 v- n( S' O- O& L5 C! M( ?& o% e" X8 S1 o- V, e& R
VC++ VB9 O M1 i& o& y4 I. L2 @, f
short Integer, j( V& w: W: c. n# |2 i9 t0 f
int Long$ h' Y" l6 G( R
long Long
1 E" [1 B0 }* {9 ~4 U3 EUNIT Long. I5 w% i# f- F# i8 @; i
ULONG Long, p' y8 g$ P+ J; O+ n6 C* w
WORD DWORDLong4 U7 i2 p/ V+ e" ~8 U) ^
WPARAM LPARAMLong3 E5 M0 o1 c+ Y
WMSG UMSGLong: o% n' T$ ^5 l/ V: e
HRESULT Long- ?, A |, v8 Q' J! Q- i8 i
BOOL Boolean8 l i; S. t$ S; G( I9 h
COLORREF Long' r4 R& B9 }4 U$ u F
HWND,HDC,HBRUSH,HKEY,等等 Long
2 P1 d, E7 j1 M9 l" Q, VLPSTR LPCSTRString) r! {8 U }& _8 o' u A
LPWSTR,OLECHARBSTR String" {& R! `, h2 u, L+ Y9 @1 `
LPTSTR String
) ]" O# x( D- p1 J; [" }$ yVARIANT_BOOL Boolean
# Z- V! ]% G3 y0 E0 [8 i4 J, runsignedchar Byte
, u S9 h, \% e3 ^6 r( O3 hBYTE Byte) b: _4 n1 E: y9 z8 @
VARIANTVariant
* s) D7 w9 s. E( B5 J(任何以*或**结尾的数据类型) Long* F' `. h1 a& K* N# h
$ a: c1 t* W( J" [5 z/ b, I8 J% K4 b; A$ J
c中的数据类型 VB中的声明 结果/ c- U, F. z$ h7 D; e- |0 M0 e
* x% | }% G2 |) z) \& Z2 s( P6 x
ATOM ByVal variable As Integer 结果为Integer 类型的表达式 $ g1 A7 G& e/ Y J- @7 V
BOOL ByVal variable As Boolean 结果为 Long 类型的表达式
% ^2 L9 ^1 Y* `# z/ O+ k; iBYTE ByVal variable As Byte 结果为 Byte 类型的表达式 2 g1 p& y2 [. j! i* ~* x
CHAR ByVal variable As Byte 结果为 Byte 类型的表达式
; x9 s4 e2 I2 Y( u n8 ZCOLORREF ByVal variable As Long 结果为 Long 类型的表达式
9 ` ~0 p* z6 D! _- A) ?5 A1 }DWORD ByVal variable As Long 结果为 Long 类型的表达式 ) \! B% H$ g( Q* J
HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄
+ B( `6 g1 n q3 p/ _& WINT, UINT ByVal variable As Long 结果为 Long 类型的表达式
2 X) I0 |: V1 h N4 y: ?; q2 pLONG ByVal variable As Long 结果为 Long 类型的表达式 ; q' Q; b+ D/ B) e) p% v
LPARAM ByVal variable As Long 结果为 Long 类型的表达式 4 C$ I. E" D( u! Z$ m
LPDWORD variable As Long 结果为 Long 类型的表达式
- _& |4 T n- M/ \! MLPINT, LPUINT variable As Long 结果为 Long 类型的表达式 8 ~9 g% P. n9 k
LPRECT variable As type 自定义类型的任意变量
: q: {) U! c- a0 C5 D) cLPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式 " j; h! Y+ g" N9 q; Y
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
" p1 G. i2 e6 @. ~LPWORD variable As Integer 结果为Integer 类型的表达式 ) O/ l% _/ H R' t9 ]( u
LRESULT ByVal variable As Long 结果为 Long 类型的表达式 : q: T2 X# N% l( I0 H7 c7 n
NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式 - C4 q9 D( N& o. P5 X2 n) a
VOID Sub procedure 不可用 ; j5 n- p5 n7 c
WORD ByVal variable As Integer 结果为Integer 类型的表达式
( i$ c0 T! e! ~; |- Q1 uWPARAM ByVal variable As Long! w+ z& ~3 N4 A, W8 G5 W1 Z: ^
9 @8 k* g6 G, g7 D3 Q |
|