|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑
% p/ T9 V! R# e1 t) T- q' L4 O! j3 c/ ]+ G# ^1 ^
. H& L6 i* `$ k% X. F以下内容转载来的 部分亲测 部分未测试
; V& n. v' } D' Z
; a8 ^4 @! [- k' B- k& U7 W0 x- ]6 t) W9 H2 D
% h1 w8 D+ y3 e: r) f/ I
VB调用C DLL时的参数传递! {% g8 P6 _* S6 B8 v; _$ R
+ X, P5 X* e8 e4 ^3 A7 f& C
函数在C中的原型,参数类型和传递方式 对应关系
! D! P! n h# s0 `6 F
2 \7 V' B. \3 f5 D9 M
! V( l2 c) C% g3 v! ]" A( b: N/ Q. ^8 |2 J1 D& d
C DLL 原型 VB声明 VB调用0 u6 \5 s7 p/ r: B9 V
+ ] b* \/ P/ a0 N: h3 c v
USHORT a ByVal a as long Call func(…,a,…)8 F" U2 \; k7 X, H! u d7 m' K% h
9 ?$ E" ~% u* Y" G/ w
int a ByVal a as long Call func(…,a,…)3 P; w( b- H: J2 e# M- V5 q9 G6 O
" c5 v& u! e' L, Y2 |long a ByRef a as long Call func(…,byval a,…)
3 S- D* f9 N! } v. e# N# u* J$ p: q" _& G; ^7 x$ g
int *pa ByRef pa as long Call func(…,pa,…)
/ n! `6 B8 u% e+ \, H. k u* g
8 T! V1 K- F9 Z" v# c- C( plong *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)
( ]7 g* g4 G% i: ?! j2 }% ]* G" e4 e" ]6 t; O# h3 r4 P7 o
LPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)
g. k1 V8 a# V' c
3 p' @, V o, B; ~$ qchar *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)8 ]& k7 S/ U7 t, e7 ]) S
9 n5 U: A x( Y) p! A
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)
+ @ K/ w, f5 C7 M! x8 a4 ?3 P: C; p/ g* ~7 t
struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3)
% {! [, i1 M- Y6 F. l& q5 Z2 Y" U: u0 X/ o4 a* l
HANDLE h ByVal h as long Call func(…,h,…) <---------(4) 3 R& ~4 i, ?* Z6 q( A' A! w
8 F9 p4 P) W' y2 D5 E$ L6 P% U$ C备注 / ^7 z9 P6 C1 o' C, j7 z
# F) S3 x1 E) w" \
1)不推荐使用此方式
: g. J- n3 R( G! l E
7 }( K/ I5 l2 Y2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 504 u2 D# o. I$ w( W5 e& ]; J
m; ?0 _: R0 C1 P3)用户定义子类型必须用ByRef方式传递, $ B/ A; O5 z/ t' `6 l% ^4 ]1 D
/ _2 D4 N$ v: s* n1 ~: _
4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。
3 W. }5 o8 T' L7 f3 o, N1 O; f
/ u# ~, ? y6 D) U" e* O$ X
+ Y+ ?( [2 t; r% ]
) Y' N% b$ |8 z# R4 B8 P' i' r) ?$ ]' O3 A6 ~1 m7 T
8 N. a2 x+ ^8 \2 e- K- B/ F2 N# O( l6 N5 x2 \$ ^+ ~* ?
4 N. {& z- C/ v3 y0 \ Z数组传递
2 h, `1 q( R7 C& n1 w4 n
" n- @* } K" t0 p+ K% Z 数组传递值用ByRef/ t: \( Q- X) M2 T$ r" O; t
4 W; {2 N, m' D7 W( Y0 W VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。( T2 v# @* |# z4 e
. m5 [# G9 Q5 j$ }- \
% I3 _' H( @) q, s" Z3 ]( c$ ?6 P
- u3 |- c' i: z( f C8 A VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。0 Q7 R0 w* P5 g7 [+ |
7 b/ } o+ f4 W( g1 V" C- i4 H: u0 G: Q( B. R6 t
+ c$ [) I+ t& X/ J! Z6 x5 N1 c
7 m! a" q- [: g
8 Z. |7 q) f$ ^- z8 T1 D# Tdll函数直接返回字符串
; E2 I, q1 K3 B, Z# ]
! ]7 R" d- [2 r. h7 |: G, c/ z. A
5 h/ @* Z% Y! e# Q$ G6 Y
, n6 g$ f: _# h4 n- h/ ^6 J# h" b VB下的字符串格式和VC中的char有些不同的1 B4 ?& b; S% w' j* c3 e* |
/ m! P% |8 K5 s: I8 b 直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子:
" V9 G" ^" F) h& Y+ c" t7 }4 ?! [2 Y, V+ K9 s* r2 \, u
, l% P: O/ W. E) p( y2 P. P. t& R0 i8 f3 Q
EXTERN_C BSTR WINAPI RetStr()
- Y% p5 w# q# d3 S ]9 u, m5 d- h7 z" O7 L4 i
{
2 z; v3 [3 G5 j5 Z; U
1 \9 \2 [$ ?- \$ ~: G/ _( L char *str = "1234567890";
9 t8 p; q$ {+ t; N: D* x4 A- m6 i: s+ [! F @' l
return SysAllocString((BSTR)str);
$ c- b5 M4 ?' _; z2 D7 y; }2 j/ h Z8 a; K' T
} : H) E, V- I# c9 O+ u+ L) d
! E2 Y* e) ?$ Y. Z8 g& g7 J
或者参考一下VB下调用GeTComputerName的方法.9 u; J; }" X0 E- y+ _
; }' L0 n- W+ O; E# U9 e9 ~/ E4 j3 M& t" z& }' b
3 H" f' H) s8 |+ r- F
$ I0 {- G. d1 n8 d9 K! f5 e% o" y$ F6 n; ]6 c. `5 q) \
VC++与VB数据类型对应关系
. E/ z) `' r0 B3 Q5 z
# A, C. {2 d8 MVC++ VB
' r7 d; C; K1 A6 x7 tshort Integer7 ~) e9 ~' }# \
int Long, K/ i2 k" a" F( k- J
long Long* J) p$ R8 v0 |$ K! i
UNIT Long7 b+ {9 z7 X3 m' k: T, ]! {
ULONG Long
' a5 U: s* I9 L: x& n3 | a' sWORD DWORDLong3 i+ ]! M9 C) v6 g
WPARAM LPARAMLong) e$ j) _. k, B( N
WMSG UMSGLong
/ ] f9 x7 A6 ?' OHRESULT Long L8 O. p$ n0 a
BOOL Boolean
* `. L2 l; e' z- R" u$ j6 a/ \& eCOLORREF Long' r6 m5 P( }2 D! d j
HWND,HDC,HBRUSH,HKEY,等等 Long) O2 U2 V) s3 Z) g
LPSTR LPCSTRString# [* L5 I J, n. ~3 q& Y8 x3 j: l+ B
LPWSTR,OLECHARBSTR String. d& u8 H* N6 O
LPTSTR String1 ^9 c, F1 c9 v8 k1 W
VARIANT_BOOL Boolean' r; W' l7 j7 p
unsignedchar Byte
9 q% X2 l# z. W& w) kBYTE Byte2 ^; }0 o% o6 i0 `1 }: L, V7 |
VARIANTVariant* e/ K# t: W+ b; a
(任何以*或**结尾的数据类型) Long9 ]: K* I" N3 c! p
% `$ [- ~: B$ c2 r7 N- H
# r+ X& P! d+ a7 ?3 |c中的数据类型 VB中的声明 结果% D0 n& T7 ^) k0 }9 M
9 I. r0 Q5 n, h$ u- q8 {ATOM ByVal variable As Integer 结果为Integer 类型的表达式 : Q; I) ^% ?- e# j
BOOL ByVal variable As Boolean 结果为 Long 类型的表达式
$ d. L9 Y4 x& H3 K1 qBYTE ByVal variable As Byte 结果为 Byte 类型的表达式
: W$ v! ~2 F0 {# {1 vCHAR ByVal variable As Byte 结果为 Byte 类型的表达式 , g& ] t* h, c1 v7 R( F. j
COLORREF ByVal variable As Long 结果为 Long 类型的表达式
9 _( F1 p" M$ {6 B( mDWORD ByVal variable As Long 结果为 Long 类型的表达式
/ A$ Z6 n+ {: q2 VHWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄 : G& T- X9 K7 M ~1 @! b
INT, UINT ByVal variable As Long 结果为 Long 类型的表达式
: ~' I- K' {/ sLONG ByVal variable As Long 结果为 Long 类型的表达式 0 H6 V' `! O1 P- ?' S3 \2 p7 a
LPARAM ByVal variable As Long 结果为 Long 类型的表达式 6 n* k8 s; Q; Q
LPDWORD variable As Long 结果为 Long 类型的表达式
3 Z5 [- G( V5 s [! cLPINT, LPUINT variable As Long 结果为 Long 类型的表达式 - [ p# F9 v7 U; z7 ~
LPRECT variable As type 自定义类型的任意变量 3 K- z/ U& t* F) J1 D: i
LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式 4 U6 r! v& M* V! r
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal) ; i. K! J1 G' x( b
LPWORD variable As Integer 结果为Integer 类型的表达式 7 q2 X! H$ K, J4 D) I7 y' Q# N
LRESULT ByVal variable As Long 结果为 Long 类型的表达式 / }) N# ^) M* x2 j6 W. }
NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式
7 u7 f; C+ U: e8 ~% qVOID Sub procedure 不可用
0 k3 g5 |( L) F' c% AWORD ByVal variable As Integer 结果为Integer 类型的表达式
# N4 _% ?, l1 VWPARAM ByVal variable As Long5 r" b& y( a( w" H# w1 z
) {) E3 K+ Z+ I& D |
|