|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑
4 s# u, z" }2 [) D! z* ?7 j' z/ s: k. I2 G: ]* V& j. X
. ?2 \- p: w [# J' P
以下内容转载来的 部分亲测 部分未测试/ w( H9 {4 I/ I
" I9 k4 V. h9 c6 m) l3 V
/ q& L1 G! @1 @1 X+ P% i' _
: U% Y6 Q5 r9 S
VB调用C DLL时的参数传递
/ q- v5 H5 n; `1 {/ K1 ?0 l" v% f, w
函数在C中的原型,参数类型和传递方式 对应关系
9 s+ S$ C2 z7 O" D' [# X* t
- H4 M8 k4 `' v8 ^( N. _, `
6 Z/ g6 b. K& L, u
; M7 h/ w3 W( HC DLL 原型 VB声明 VB调用$ ^$ {9 f( R3 u5 n! S% o
* `' Y9 F& c/ x! o
USHORT a ByVal a as long Call func(…,a,…)
2 X7 b; c' H7 a2 _4 q2 S
4 x6 T9 i O9 L. x4 xint a ByVal a as long Call func(…,a,…)
1 F; d8 Y; S& X$ n$ J$ w6 I4 P) n! L" v& l
long a ByRef a as long Call func(…,byval a,…)
/ _, V6 x& O9 U# E; [
( [; C6 |1 V r u7 j# ~" o( K8 `int *pa ByRef pa as long Call func(…,pa,…)" _3 C2 k4 L Z2 I! p8 ^. B6 N
- i+ r1 k( _! Y* c! [7 Ulong *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1). Z/ e+ S5 v$ c3 g4 J% j
) ?# ~3 H7 c3 o/ n
LPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)4 ^: E/ ]6 E% o9 _" S
9 ^0 P! ^+ l1 _- b8 D$ L; } Lchar *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)
9 f5 m9 z+ H; K# }2 ~. b7 Z& C1 Z( m( }" y. L0 c
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)1 X8 l" u& F) f% Q5 v& c
- T. P3 ?8 |/ ^7 O. A( F/ zstruct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3)
& S; Z! z9 ?& W. E" a4 n+ G, K3 Q# ^+ Z/ c* j8 I
HANDLE h ByVal h as long Call func(…,h,…) <---------(4)
% w# f/ `+ b; T5 o- k. X! q$ c4 L8 f
备注 # N$ E+ ]% ]( B4 @: V' ^. n
! N! ~ @3 W" @" l$ Z \
1)不推荐使用此方式 }" z8 B* j- O; C# I9 _
7 o& S- m: @ u( c. u
2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 50
) ~& q- L$ e8 P" V1 F- s9 c7 A1 r5 p+ U2 d- ]1 y& Q
3)用户定义子类型必须用ByRef方式传递, 0 L. ^6 v0 P+ J+ x. d, P
8 [* z( U* O! I
4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。
+ r% k* L7 J+ r* ?. X* z6 v f5 J1 R3 v+ [1 u
& N6 G* R6 l! q& p/ R- a' e
* v B' j5 }1 f( V; |
+ o* [7 n' u% @( A: e d0 s5 K, m4 w
9 L7 W3 M( u" D# Z
, K7 {5 ~( Y& Y% C' u, @4 ^
数组传递 % `8 } @+ L3 ?: v: N, h+ J
: {: |1 S# Y* ^9 a% Y 数组传递值用ByRef. N v( k$ r) V: Y
* j$ U0 a+ k% Q3 R
VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。0 A2 G/ j, m& k5 m
" R9 l( \- J, R+ {. y. x& y) o% ]* l
- | f8 a. x) k3 U; b( R
; ~/ k" s' H g5 [& A VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。2 x0 Z) B6 R* R/ `4 v- t' g' X
# Z/ [/ R; z& s3 A+ s
2 h9 y2 @0 P# t7 L: ~9 Z
/ ^3 t1 H1 Y3 d. m' ^7 R* y$ G+ J0 a
; l0 _5 j% Y5 q8 ^
4 G! k+ D- ^/ Z: o3 S: ?4 Vdll函数直接返回字符串% f0 u+ ^& j3 ?2 G& @" h% B
: q: y2 [& @3 S, T; q0 O0 G5 K7 @0 E# [$ v+ C. Y
2 L" t% U8 C, q- |/ Q& }3 }# G; E VB下的字符串格式和VC中的char有些不同的! u5 V* E, ~; C. q
8 e5 M- q5 w& _' I
直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子: 8 v% x- r9 l6 c% F) b& S
& Q/ _, ~' K# V# i8 C
) U3 C1 J4 B1 U4 f
6 i4 I( ~% x! ~7 P EXTERN_C BSTR WINAPI RetStr() 1 x5 H* a9 q9 Q" U" z% }
% h5 G+ Z/ h( p& d$ {( T4 T. e
{
& O& W) G1 v5 W+ @/ ^, p
/ e% I' Q6 n# r1 V8 b; d: k char *str = "1234567890";
5 d8 l6 Y( P6 f$ G- L% u5 _
. e8 M3 X6 r9 n$ C9 A return SysAllocString((BSTR)str);
) S' ]5 t3 t$ {0 j; X3 ]! A- F* e' K+ A! M9 h
} , ]: n% {. N3 e
' Q; X% N" A: }9 g' W9 Y
或者参考一下VB下调用GeTComputerName的方法.+ g$ ], J6 f0 m& y, I& {2 F1 ?
4 [" D; H- G# I7 p
& f! c* {) L2 G3 o: T$ S' U
( a6 W0 ~& v& v* L2 @+ B0 \- d6 |- O# f2 N0 |" e
, P6 X" O0 y# |( g/ I
VC++与VB数据类型对应关系6 H& m# M; S! G; h) e# ]
! A" e+ e( E+ A, w6 YVC++ VB
" T/ p, F) f6 ]/ d3 K, X3 I. Wshort Integer
/ y' n1 y/ D1 E( P* u' f& Nint Long0 y1 Z% O ?. I* Z2 L) w% B: F( B9 \
long Long
" V6 T( o* i2 z+ D6 xUNIT Long
4 D& F3 q7 b# m9 F' A; R) t. IULONG Long. |9 U2 M0 H/ Q% d( P
WORD DWORDLong6 o& `2 T3 @9 W: R
WPARAM LPARAMLong, |. P8 E% |$ g
WMSG UMSGLong
, u2 o. B3 ]# c P/ ^HRESULT Long
: ~. k0 N- T1 t0 B# t! wBOOL Boolean1 M7 A/ T& `& \( I5 {9 A$ }
COLORREF Long5 V6 a' a5 z$ O/ ^- ]& c9 D8 w
HWND,HDC,HBRUSH,HKEY,等等 Long
! U( G+ t) v. M6 D- Q: W! o* @6 E9 E; JLPSTR LPCSTRString: k) U/ y& j& h9 F
LPWSTR,OLECHARBSTR String) ?6 j& H0 A( ]
LPTSTR String
- N; r& o# q' f& p, MVARIANT_BOOL Boolean8 v. {0 `3 C7 }% y2 H! X1 \& T/ G
unsignedchar Byte
) G- T4 U1 W. }$ h; _BYTE Byte) n0 V$ b, P( p! m& f9 Q- i
VARIANTVariant& z/ X, ~/ `* O5 K* G
(任何以*或**结尾的数据类型) Long4 N' x1 ]8 H& y' I
* Q: y# S% e& B% }$ e
- A- l5 y9 W- f+ E9 c( T; vc中的数据类型 VB中的声明 结果
, z0 G! K3 m- l) f1 O4 n # s# ^2 m" b4 }1 k: R* J
ATOM ByVal variable As Integer 结果为Integer 类型的表达式
2 e6 v# A3 J( o; `5 x- ]BOOL ByVal variable As Boolean 结果为 Long 类型的表达式
- k/ X' d( T5 dBYTE ByVal variable As Byte 结果为 Byte 类型的表达式 x8 o8 K0 {" p2 y( `/ i
CHAR ByVal variable As Byte 结果为 Byte 类型的表达式 $ i& M! |1 v, F+ E1 B
COLORREF ByVal variable As Long 结果为 Long 类型的表达式
* v: G" E N1 b# o" G: V) nDWORD ByVal variable As Long 结果为 Long 类型的表达式
, I2 J0 t5 O5 h' E/ GHWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄 # c& S- [6 v+ J' N
INT, UINT ByVal variable As Long 结果为 Long 类型的表达式 # Q0 l$ Z# i) k o$ L# `
LONG ByVal variable As Long 结果为 Long 类型的表达式 5 ~ ?+ H' l' g
LPARAM ByVal variable As Long 结果为 Long 类型的表达式
/ R9 r H. u! @7 w' H) f4 T: mLPDWORD variable As Long 结果为 Long 类型的表达式
5 W3 ^3 W! L, L/ p0 v1 bLPINT, LPUINT variable As Long 结果为 Long 类型的表达式 * Q; F+ `/ d& I; n+ {
LPRECT variable As type 自定义类型的任意变量 : f9 o/ C( w) ^8 V! R
LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式
' O- f) W) L; CLPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal) ; o: G ?% P( B6 L# o" r! x1 w7 d
LPWORD variable As Integer 结果为Integer 类型的表达式 * T% O) E# {+ f- y: }- E
LRESULT ByVal variable As Long 结果为 Long 类型的表达式 , S0 d& ?0 g- u1 F8 e$ C
NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式
# m) W, K9 v1 T) g. m( WVOID Sub procedure 不可用 + G" F: j, l) a( i2 }
WORD ByVal variable As Integer 结果为Integer 类型的表达式
' @7 f) a7 @, j" m% [' r8 YWPARAM ByVal variable As Long
# i7 i8 L3 p! C# [- X0 F5 `. s' _% t" a5 F$ `& H
|
|