|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑
K C% i) v, X j+ b+ E5 n: K3 [+ _0 o
9 _ s' F% ?5 h
以下内容转载来的 部分亲测 部分未测试
( T- s, V/ f) Y' U
7 y( A, b1 K3 P, L+ i) L- z5 d0 D: c+ F ~( q3 \( G; ~
/ U. Q- d6 `; k5 u
VB调用C DLL时的参数传递
0 Z# ^+ Y+ } H% F
, o# d: p0 o! f7 C6 U# n# A+ g函数在C中的原型,参数类型和传递方式 对应关系 8 H6 n, c0 P! w( a7 a0 @
& G* G2 _* y; }9 S: q. }5 _+ {- d( _/ B, n8 A5 Y4 o
$ j6 ^9 C* R/ o# L8 H( W7 v
C DLL 原型 VB声明 VB调用 }5 X c4 N( E
0 h+ A6 ~$ f6 H3 s
USHORT a ByVal a as long Call func(…,a,…)
1 t S+ C2 w1 ]8 A. L% ?, y) _$ y! r2 H% V6 F+ F- M: R- i
int a ByVal a as long Call func(…,a,…)
: q+ ^- a1 H6 ?
" W j; g3 K) K& P1 M8 ?long a ByRef a as long Call func(…,byval a,…) V9 h8 ~; r& [: q
: [3 h1 Q+ k/ k6 T2 G
int *pa ByRef pa as long Call func(…,pa,…)9 B3 h5 w" G; [& R/ @
; [, G& e% A) a* i
long *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1)" z% F$ V. y% O+ P& D5 r
9 n, ~7 t& B& F2 F% [: X1 P
LPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)% r1 E k& o% U' b
8 v/ D- @, k0 K
char *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)3 U3 ~0 A, o5 s! D# M# ^2 h
% {2 C3 m* }7 {
wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)
0 Q- \1 C8 N! K" W, Q2 t. b+ { h
struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3) ' {9 g D% w$ _4 E+ r$ s
' I6 q: A7 H% ~+ x& rHANDLE h ByVal h as long Call func(…,h,…) <---------(4) ' A7 t/ A5 D& H" d: t4 O
4 ?9 U9 Z9 Q' z7 }备注
, n5 ^' [( K2 W, l& k# U0 E4 V2 G$ m9 m
1)不推荐使用此方式& t; D8 W8 k2 J% `+ J
8 q/ H% J2 ?% l5 ?4 I3 x, v2 y# w
2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 50
/ d/ h% Q( i0 P. N+ G6 _% | y7 u4 r1 ?( E
3)用户定义子类型必须用ByRef方式传递, ! k, b6 W5 o* o8 {9 k) a8 S
$ ^$ s/ M/ _9 x) @; ^, c
4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。 , c8 g( R% Z h( \
' Y: t7 j0 g: ^; c# s6 \( w2 |2 R# r- X. L) F$ D" k; J* b
: A; O; [2 H% H. S# [; `, o3 m
1 q! u8 o! S) B
/ @4 l/ ^: ~6 ~' ^' Y) P: S2 j _ g9 s# \/ o+ J
/ H( B3 r5 e$ _* T: X8 Z v
数组传递
; J4 _7 A# t, }0 I3 H+ P
8 u/ }: ~5 H. `2 H 数组传递值用ByRef
, H% V! e6 ]" x! t; h2 K) L
7 W7 M( j9 T# M9 H5 L6 w9 R VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。
, k( R( L, r# ?9 `5 H) M4 H* i7 J1 w8 e7 Z1 ~4 _
( g( | j9 {1 |; I( g1 z9 D% `% w1 ~
VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。
@. u; f! W% X, g
; a8 Y; a6 V) D$ l+ X1 g0 v) B; M9 Z+ k/ u3 A8 e3 {+ Y. u# x
, r% y. z( I3 K5 a Z: {( Y* b) W. G4 l( v4 R S# M
$ y0 ]' \4 l9 n q
dll函数直接返回字符串8 g7 @7 J# ^* l6 f8 G9 m
" A; O& U9 }. i- r! U$ f; a& @. G# S0 X+ N
2 |$ j) y! ~, \4 m VB下的字符串格式和VC中的char有些不同的
1 J$ P7 ^: v% I5 o! e9 E
" ] s& k# M5 X% F- t$ l 直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子: $ s/ B' f5 m1 C
2 D5 F' W# e( x% y
+ S+ A r. s8 m; R9 |7 p9 f: f1 ]2 {3 x6 P6 R
EXTERN_C BSTR WINAPI RetStr() , \6 u$ d4 b. l$ x6 T" T8 c" I" l
$ [% R0 d C5 A3 Y2 R! Z. E
{ * G3 d1 m1 p. ]) ^" l
9 q/ T4 c1 L+ P6 L Z3 ? char *str = "1234567890"; & a v8 T& C: s( a9 f$ x" e4 F, K5 b
* W6 B! }9 r" W$ q; ^( Z9 P, U return SysAllocString((BSTR)str);
/ k# n; b4 K# K* i' R% G9 G" y8 o! Z' A/ E: {- X9 j
} ( \% U% A+ n, h/ i& W
: a1 c7 t6 g" B) _) b: B( J或者参考一下VB下调用GeTComputerName的方法.2 i: X4 B. E% K3 m N& a$ ^
1 x7 b' C# l2 V* z5 z
1 p& b2 ]8 g2 i* _) v
2 H; y- {9 Y F D/ d6 F/ [1 P$ L4 q# O) S/ m+ O
4 k" L2 D* _5 K; m$ l VC++与VB数据类型对应关系& n4 J3 t6 I1 |$ h: P! L# W1 [; V
: L7 }/ e* D& t; E$ _7 Q; p6 W9 G
VC++ VB
8 M' [4 g! M7 E2 X' Mshort Integer4 A+ y5 J6 @# n& v. h
int Long
4 E3 c8 z4 ?- z2 b# Q* Klong Long
* u% H. W7 I1 y* \4 M0 k0 A5 PUNIT Long
/ h2 C( n2 t9 V/ n! A/ ~ULONG Long
2 d$ J% x5 E. j$ s5 f- pWORD DWORDLong
3 G1 l7 A$ z u7 x5 [. JWPARAM LPARAMLong8 J4 B3 z8 A+ j
WMSG UMSGLong" p0 c& z9 _" d2 I, M0 p3 R/ h
HRESULT Long0 P1 {. d" o; ^- t5 Z& A
BOOL Boolean- ^* [$ m( \1 U( G3 e
COLORREF Long
! n; B T+ z; ^! p- t E4 X* c5 C' {HWND,HDC,HBRUSH,HKEY,等等 Long; _; ]. a1 O$ E! }! @
LPSTR LPCSTRString
6 X; j$ n% q4 U* r) x4 w9 \LPWSTR,OLECHARBSTR String+ l* m0 s# d, b; H4 U/ u
LPTSTR String+ j |' ?; }% N
VARIANT_BOOL Boolean
( o( b5 p- @2 ?# u$ Q* eunsignedchar Byte
! V& v1 o" N) e6 A% |8 X' PBYTE Byte
5 T3 [" W- p0 R7 Z) ~) l/ [VARIANTVariant
/ B5 _7 X9 R9 A. v(任何以*或**结尾的数据类型) Long
% D0 p; Q1 [9 p: q& @" f0 V# i' j$ n7 n) M8 j" Y
?* Q, M- X% b. U$ X* t1 Q# s; A4 ^
c中的数据类型 VB中的声明 结果5 O3 d. R: Y/ l9 j
2 C5 U2 [1 ^9 T: U5 h8 d5 L
ATOM ByVal variable As Integer 结果为Integer 类型的表达式
6 h" n5 a! J' G, `# P/ U9 jBOOL ByVal variable As Boolean 结果为 Long 类型的表达式 * {3 i/ y1 \' V0 |. F
BYTE ByVal variable As Byte 结果为 Byte 类型的表达式 / R% _# `4 ?! ]' e4 R; A
CHAR ByVal variable As Byte 结果为 Byte 类型的表达式 & `. i" K/ B1 q2 p+ E$ @- k/ R2 t7 u( \
COLORREF ByVal variable As Long 结果为 Long 类型的表达式
* y) t7 ^# g( yDWORD ByVal variable As Long 结果为 Long 类型的表达式
) ]& J6 j, W8 L/ [) `! h# ~7 `: CHWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄 s" V2 T% D- U8 e
INT, UINT ByVal variable As Long 结果为 Long 类型的表达式 A0 F. |+ u7 j9 {& j, H8 x
LONG ByVal variable As Long 结果为 Long 类型的表达式 8 o. z: F9 l q" m+ r0 e9 s, \
LPARAM ByVal variable As Long 结果为 Long 类型的表达式
+ p+ ~% H6 v Y' q8 G6 A, lLPDWORD variable As Long 结果为 Long 类型的表达式 ) v5 g7 h6 X# X3 r8 C
LPINT, LPUINT variable As Long 结果为 Long 类型的表达式
. `3 `* e/ P u" eLPRECT variable As type 自定义类型的任意变量
/ |1 D @" p% fLPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式
" T9 o3 l' b5 R( @LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal) 8 m2 U+ `1 n# s+ V9 s( W
LPWORD variable As Integer 结果为Integer 类型的表达式 ; `& n4 q; Y1 A1 ^ V! ~/ z
LRESULT ByVal variable As Long 结果为 Long 类型的表达式
' b# G# {0 @) } v+ ~NULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式
% ^% l2 \; |" K) G7 a) H+ VVOID Sub procedure 不可用
/ v' ?* T7 r$ H. y1 n4 l; S3 XWORD ByVal variable As Integer 结果为Integer 类型的表达式 # j* _+ Y" N1 h' |2 B
WPARAM ByVal variable As Long6 U) `5 V& U, ?- N# R
7 F' x8 H6 l+ M a; n% H& O
|
|