|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑 0 S' b: Q1 t1 @, I
& I! q! ~5 s* S) w4 n) A/ H
# }9 G# X) _. |. q以下内容转载来的 部分亲测 部分未测试
7 m! f& y& h7 F* {7 A6 F# `9 d% l# j9 N6 S/ d( m
" Z8 N$ p% D* r5 a
, |$ b) j9 ]- pVB调用C DLL时的参数传递" X" w. j! l8 Q0 T# r, e4 T
7 D5 h# X0 }5 B% Q! `9 u函数在C中的原型,参数类型和传递方式 对应关系 - \/ m; w. V/ r! g0 Y. Q3 j4 Q
) Y. N/ o) b7 Z
7 Y6 C# Z }) s( z$ o# \+ P& P* N- `2 z
C DLL 原型 VB声明 VB调用* o" N t# X; z& |% F0 a
- ^5 c8 O' P& N4 t$ |$ U
USHORT a ByVal a as long Call func(…,a,…)
: `& Y- E2 c. r% I/ q2 l* \# h J& l& h" ]# ?
int a ByVal a as long Call func(…,a,…)
/ B- v2 e( e( Q9 p* U/ O# h- g4 O' N. j9 }- ]2 Y
long a ByRef a as long Call func(…,byval a,…)) ~! [- M0 s& ?1 b% C! M# W. U( b
/ h( ? o6 r) W8 P, Qint *pa ByRef pa as long Call func(…,pa,…)# t. z2 h* q; o M1 `9 g
( K. x7 k- E ^1 K6 along *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)
A0 u% U* |5 i! T3 d! T, y! S1 P) g
, X1 B2 h# ^4 ?% j/ k* Y8 A! C$ zLPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)
' m' }7 D4 Y1 i) d# ?" R9 ^5 h3 m8 K5 Y6 G
char *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)- ]5 c! y4 s# h- Y7 X3 R2 d
" i" t: ?* v& N1 N: D) {
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)
1 u+ G( H4 j6 P1 g7 _5 g4 B. }' O# ^* m! J' f, }, x, E' q5 B
struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3) # X+ Z! w0 E1 t' G$ J: Y8 D* t/ f
2 V5 j4 |5 A ]+ tHANDLE h ByVal h as long Call func(…,h,…) <---------(4) 8 T Q( x1 k; z% ^+ o C
( n# O z8 @9 S' r5 R* k/ U备注 6 N: Z/ A. w3 `5 c
+ [7 |' r+ i/ a. _1)不推荐使用此方式3 x$ Q/ {) A: {/ d. f
0 ]" P- j6 B/ D0 S
2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 509 ~/ H! i/ o7 X) i. v
. Z/ ?! ~ q u1 U3 o3)用户定义子类型必须用ByRef方式传递,
8 p0 Z+ C( ]/ d+ u2 g' l, `: R8 O' o2 Q4 {
4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。 : c% _! t) w N. c1 E
$ J" ]9 ?8 T. }. Q- W: @
" R+ k8 p! Y- e! u
+ d+ N, U* o6 @/ N, O" U/ v6 t
' ]9 W& H5 w8 V N0 N+ E
$ Z; i K: p0 c, g2 o! w) k& R! L# \. u0 W
# o, j+ p& c9 y: s+ F
数组传递
- \2 w0 g9 V+ B- J9 o
. s2 p, x: {$ T' m 数组传递值用ByRef
. r( \/ x/ Z2 H% w3 H
9 r* X7 a6 }: M: ]) B" B) X% W VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。
/ {' J5 i# h ~3 L6 e/ x* B M1 D x# G
( t( x! p4 {8 Y
' ]* b1 J! k4 z
VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。
}/ E6 C9 M5 e1 A' H- |- g" ?
9 t# z7 h5 \0 f* Z, U( ~+ z. O
( k; i$ A2 X1 q0 d# x- U) @0 A% n* H4 w* G* d- |4 Q
7 J3 ], n, ]& i" q# Q2 a8 k' i& f# |
dll函数直接返回字符串
2 w5 c6 |# r; R E% f
. h) @ x( X$ `8 U; t6 r8 a( @% K" {6 X" ?4 V4 ~
( X( ~1 U( S- z
VB下的字符串格式和VC中的char有些不同的' N+ `4 v5 s* z# F% a
/ ^6 @0 Y O" P2 p, f4 n 直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子:
& W1 z: e4 W4 h/ c- z
- {! Z+ { n* V, B8 ?
+ g# ?. Z" z7 b6 C# i
$ B* n8 B* i: \1 x' h EXTERN_C BSTR WINAPI RetStr() 7 G+ x! Z! i& y+ Z; s
) p3 y7 T0 q6 o/ N4 { { ; {" t4 z8 q4 J4 v h
8 `$ B. m) j* e9 p7 @' X1 \
char *str = "1234567890";
& U1 G; C' Q5 p2 e5 L+ i
! h- k) x/ z6 \# Z; j1 w- q return SysAllocString((BSTR)str);0 a6 l [/ n; V5 d
) x$ u6 ]- [3 O) }4 r }
" }) d4 S7 E' A. i+ T6 ~% X5 Z( ~
5 r& {& w' x1 ~0 D; [或者参考一下VB下调用GeTComputerName的方法.
# I4 I' _$ E: J9 g t/ M, x$ w, {' h6 s% m$ g& a9 X) l
1 G' _8 c7 m! n$ b# n- t9 V5 a5 X9 A( m
9 Y6 C& K2 b. B9 ^. W
: z d) e! O. V5 v- I& g. ~. {. k
/ {: V/ ~/ ^* u5 k4 [ VC++与VB数据类型对应关系
* M4 \: J/ w9 x5 A9 W9 j
+ {/ |. N8 s1 X/ hVC++ VB6 _( }5 C' I E: r8 d* T
short Integer
3 b+ h ?: r% T7 ]8 [2 n+ V, t0 l% mint Long7 i- j5 y/ r' `$ c. }: F
long Long% ]/ D5 h( ?9 I" h X5 `
UNIT Long
( t+ d+ t0 J$ x( r) a* `9 b6 H) vULONG Long/ v9 y! [5 O# B! ?6 }' H
WORD DWORDLong
4 [ V" X& u$ z( i! aWPARAM LPARAMLong/ K7 | U- G$ w5 Y$ x- a& R
WMSG UMSGLong
7 d# _2 S) |: ^3 M0 N Z2 zHRESULT Long. X- V* {1 x/ ~; b4 b' N, o+ l
BOOL Boolean# K: X d$ ^. t8 O+ d' u, |
COLORREF Long9 F8 E4 y: y8 b: @
HWND,HDC,HBRUSH,HKEY,等等 Long
( ~- W/ k' }+ ~LPSTR LPCSTRString
% g @! W) o! J, ], n& FLPWSTR,OLECHARBSTR String: Q! e$ \/ L4 x) Q: m
LPTSTR String( T+ M0 S/ ]2 R$ q; W" u9 [
VARIANT_BOOL Boolean
; L3 X, [0 I* t0 t& B: Funsignedchar Byte
: |/ w. I1 d- `; b* d4 pBYTE Byte; C# \: y: @( U: @9 L
VARIANTVariant; x1 ?2 T5 z. q, ]% |8 ^6 L0 O; f
(任何以*或**结尾的数据类型) Long. [9 R2 u8 |3 g- \
8 K5 l, Z& o. a% Y4 [6 M% i
5 e$ d' }8 c- a/ v
c中的数据类型 VB中的声明 结果: r5 l8 |- B* p) n
: b7 d# e+ J+ B( T/ x; LATOM ByVal variable As Integer 结果为Integer 类型的表达式
% w9 o. x* W2 P* @( j( pBOOL ByVal variable As Boolean 结果为 Long 类型的表达式 / Y) F" ?) W* h/ E
BYTE ByVal variable As Byte 结果为 Byte 类型的表达式
@& W4 }1 h( f1 r1 K% V! Q% uCHAR ByVal variable As Byte 结果为 Byte 类型的表达式
6 [6 f; ~+ K4 K1 Q( Y8 F8 `COLORREF ByVal variable As Long 结果为 Long 类型的表达式 , {2 _- K) l6 O9 S8 Q. T, v
DWORD ByVal variable As Long 结果为 Long 类型的表达式 / o+ T3 O! T6 r, c3 m
HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄
& d: P+ Y* e4 ~3 `5 l! o/ XINT, UINT ByVal variable As Long 结果为 Long 类型的表达式
; \% F0 u# p) I6 p, y- |LONG ByVal variable As Long 结果为 Long 类型的表达式
9 u# @( Q& ~1 z, k, }5 T4 c. QLPARAM ByVal variable As Long 结果为 Long 类型的表达式 * {0 D) @+ ]% b% ]7 {0 h0 j. F
LPDWORD variable As Long 结果为 Long 类型的表达式
8 R( U s$ b( g* s8 j: }LPINT, LPUINT variable As Long 结果为 Long 类型的表达式
3 H: O* Z+ p0 v2 F( ?& FLPRECT variable As type 自定义类型的任意变量 2 l! p! ~9 H/ U7 Z) B5 c: J' a0 f4 \
LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式 # d9 F- C- |3 j
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
7 i) i. A% p! F2 C. z0 A, _LPWORD variable As Integer 结果为Integer 类型的表达式 x, T& x# g8 Z- k8 a* n- U
LRESULT ByVal variable As Long 结果为 Long 类型的表达式 9 \5 i; |6 h8 Y0 T
NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式 : t; a& d t1 K2 \: x; x! m8 K
VOID Sub procedure 不可用
/ J( W9 I( T5 Q/ ~WORD ByVal variable As Integer 结果为Integer 类型的表达式 # }8 @! |( M) ^) S/ Z
WPARAM ByVal variable As Long
/ ^- H# K6 v% N# |( y" @' ~' v' D) x- \4 s2 s
|
|