|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 15757753770 于 2016-12-11 15:09 编辑 - f" c1 _& A9 V9 `' y
E6 T. \2 [" @, M9 z' \
0 {% s+ K( z" D$ x7 y k1 Z1 f( r以下内容转载来的 部分亲测 部分未测试
7 j5 Q3 w( O z, ]5 G: i) c, \2 [0 ]* R9 I% b6 B* z" H
5 s3 Q Q7 \& K' D' U
" E p+ K: L1 P) PVB调用C DLL时的参数传递( K! Y4 H# b; l
% V3 O8 F, `7 |+ o+ C: Y
函数在C中的原型,参数类型和传递方式 对应关系
; h; {5 M* c) p* g" p# r& V
; k1 V1 P/ U I! q8 W- q A8 q" H' r) w' x0 [
( d4 D2 A! x, Z1 \3 e+ `$ h
C DLL 原型 VB声明 VB调用
/ w7 n' D0 h; a8 t+ D7 \, ?0 a0 u3 i8 M4 ~
USHORT a ByVal a as long Call func(…,a,…)
, F7 i* _" l3 M( k8 T; m) R* M$ P3 i9 R+ f
" i. t# U/ V% Jint a ByVal a as long Call func(…,a,…)
5 H" k9 K& U5 A( K- j) g2 g2 D0 U
s& e. P: w4 r/ R: v" slong a ByRef a as long Call func(…,byval a,…)2 c c/ U& L7 b) M6 M0 Y
/ I) w; F. Y' B6 b4 H# ]
int *pa ByRef pa as long Call func(…,pa,…)$ i1 W7 d" p d8 V& z N, g
8 U' ]# f) m5 S. _
long *pa ByVal pa as long Call func(…,varptr(pa),…) <---------(1); t% N* a: |2 v4 K
5 V. L! M. r$ M8 p* b7 d
LPSTR lpStr ByVal lpStr as string Call func(…,lpStr,…)
+ F0 C N J: u# x- D i
6 D2 e& s7 A9 k; Kchar *pstr ByVal pstr as string Call func(…,pstr,…) <---------(2)
" H @+ @) ]+ c4 I ^
# I$ M+ f9 c- Q7 c! M+ j# b+ Y, \wchar *pstr ByRef pstr as string Call func(…,byval pstr,…)- {/ H$ b; [; e4 h7 Y2 o! C/ f# _
/ S4 _' x2 Q q2 F
struct tagX *p ByRef p as tagX Call func(…,ptag,…) <---------(3)
' d. V" R! N: H3 ^! _9 F4 h M! n) \0 N S M4 Z
HANDLE h ByVal h as long Call func(…,h,…) <---------(4) & W: l( ^, V5 }
8 O4 B$ ~4 n* \% d1 {# R, U备注 ; G* p' b) T2 _
1 } L( s& P$ j$ L, f
1)不推荐使用此方式
$ e5 w" N3 r J; Y. G' u1 T G+ M9 A/ k* J2 Y P3 s* d v* r
2)如果DLL要求一个字符串缓冲区,一定要在调用前初始化字串,即dim t as string * 50' e. G- K7 K, O( c# Y6 q1 Q
7 w$ O$ O0 l! E/ J+ K( Z
3)用户定义子类型必须用ByRef方式传递, ; f/ v* V) M4 O2 l( X
+ O- L" C( K1 ]& M1 d4)任何内核对象的句柄(process, thread, module, file, filemapping, semaphore等)和大多数GDI对象的句柄都能用此方式传递。 ; n9 |: k# q1 ^& o- O
3 ~4 [$ Z3 B9 G4 z; V. P& k8 X& T
8 {; X' P: f* b1 ]5 W( q
; D. N! Y3 E, Q* ^2 @7 E$ ]: m: N% \# G
/ q" N$ V/ Z8 ?4 y( i: @* N
; B6 Z1 Z$ k3 [
! @5 W* p" U, I" F+ r" c
数组传递 - g1 C% X& v: @! d9 J" i! `
0 v+ B8 v: w, Z( q( i
数组传递值用ByRef' V( K* A( Z* ^6 m; L
; ]. c6 G( a. [4 S: G2 _ VB地址到VC的传递,只需要将数组第一个值得地址作为ByVal参数传递过去就可以。
# U7 v. h7 X6 K
2 t5 H3 e4 q% Q7 h" b( d; _/ K$ d6 m; |8 n
' S O( O, d2 ^8 z9 e VC中的数组的第一个的元素的地址传递到VB,只需要通过API函数CopyMemory就可以将整个数组拷贝到VB数组中。& E0 I& _0 {5 t8 a: z6 |
$ l/ p3 M4 O/ C$ f) O" m, s, j( t/ U: \6 L% p
5 N K/ y# |" e Y8 j& ]+ ]% q1 a1 Z) G/ h9 u
% ~: D1 I0 u$ g$ hdll函数直接返回字符串) P/ \! d* W* F: e& m- p
9 P8 P0 B, T, R* A$ ^ r$ |: E& o8 Z7 J i
9 h; w) j+ w! y9 \% H4 P, A
VB下的字符串格式和VC中的char有些不同的
+ S+ q/ R* t+ I5 f+ Q, t) a, Q0 W6 z
直接返回char *是不行的,VB不支持这种做法。正如你在资料中看到,大多数都是在VB中先给字符串分配空间,再传递给VC,在DLL中可以修改字符串,但不能超过VB中分配的空间。如果你希望直接返回字符串,必须使用BSTR类型,这实际上就是VB中的字符串所使用的类型。下面是一个简单的例子:
+ @) H# h7 F( f) S2 J& [; N: K; F& I6 u8 T
d% q) ^( K5 z2 @+ U6 `0 Z! ~$ r8 a5 Y* d6 ]
EXTERN_C BSTR WINAPI RetStr() 2 H) T0 {( C. v5 D6 `2 u
( g9 t: R8 e+ A' O* ^0 t, P3 n# d
{
1 s, B& N( k5 X/ e; [
/ Y/ Y* h* |" N4 J9 S( m char *str = "1234567890"; # F" r% E* s ^$ M; S3 E1 F
( a) w7 i- M. Y" Z
return SysAllocString((BSTR)str);6 F; B$ w$ e1 j: T, m) d
0 ]5 z& }, L, k( ?4 c2 W1 ^
}
& x4 J9 h! z, R) J; ^: _6 w
4 Z2 e, j$ Z4 a! L9 P% i) i或者参考一下VB下调用GeTComputerName的方法.
, }) M4 W8 { E2 t3 m
6 @" R+ l a' ~/ w+ p, g8 u9 X, k9 ^
+ M6 ?5 o/ U0 q! i/ c
% v- c6 `+ p! A4 M; H6 O; G5 a ]& S' n1 `! u. ]
VC++与VB数据类型对应关系
6 R% T' o# V( T# _
' U: ~9 x+ n" _+ R) _- I% ?VC++ VB9 ?) W5 l% C! P! j8 `/ {
short Integer! n0 e/ q$ n- r7 z7 l" s
int Long
5 p! g9 ], d0 d1 U6 Flong Long
5 X: w" R) y. }8 M! L' L! s) ?! CUNIT Long& B# n5 u8 |9 ~0 F9 A: e
ULONG Long# s# K1 {% i$ g, P/ r+ U, W# P
WORD DWORDLong
9 h/ Y. A5 c9 R. `0 oWPARAM LPARAMLong
! X% `! K* H$ ~2 |6 o2 i% iWMSG UMSGLong
5 }1 i: d7 a2 P/ S' ?8 x% fHRESULT Long
, Q- p1 F" h" [1 w5 cBOOL Boolean( f0 t- d+ Q# \& C! q( v
COLORREF Long
" T2 |7 m; F+ ^; r9 {1 IHWND,HDC,HBRUSH,HKEY,等等 Long( }& n! R% O; \! ~
LPSTR LPCSTRString( K" T4 g' i' @6 s, {; i1 _1 O
LPWSTR,OLECHARBSTR String
$ k, k& |: j% N6 yLPTSTR String
: F& d% w k2 C+ T* d5 EVARIANT_BOOL Boolean( ?# w$ W: H8 V0 j R3 v" b5 J
unsignedchar Byte0 c4 v/ g6 C; R& {' x
BYTE Byte
" g& z8 V& p5 z3 y7 R9 YVARIANTVariant
! Y, B* o" x4 A( y; T( S, O% R$ h7 U(任何以*或**结尾的数据类型) Long1 X: U7 k" }$ i8 N. p0 k
, X( y1 ~4 P& s- v6 N, U! V( _
. z9 d$ X! \; E: x0 @) kc中的数据类型 VB中的声明 结果, N; F4 V1 {/ t% O! J
& k0 H. ]) H: k) U
ATOM ByVal variable As Integer 结果为Integer 类型的表达式 6 Q' ]" f: ^# ]; S
BOOL ByVal variable As Boolean 结果为 Long 类型的表达式
# Y' D$ T6 Q( ~- j. o* sBYTE ByVal variable As Byte 结果为 Byte 类型的表达式 ( p. @1 R! S2 T2 k7 c4 A) r* ~
CHAR ByVal variable As Byte 结果为 Byte 类型的表达式 2 X3 d+ \/ _4 A6 k7 L) \: {
COLORREF ByVal variable As Long 结果为 Long 类型的表达式
! E6 ]% V0 G; dDWORD ByVal variable As Long 结果为 Long 类型的表达式 4 N/ v$ N# c. _% a0 r+ D2 A
HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄 4 Z2 M+ B, k" F u7 \, U! [
INT, UINT ByVal variable As Long 结果为 Long 类型的表达式
/ b4 O h/ z8 s3 z; H9 oLONG ByVal variable As Long 结果为 Long 类型的表达式 , f0 A) B2 ]' C+ w
LPARAM ByVal variable As Long 结果为 Long 类型的表达式
T+ V! N8 j% p. ~: FLPDWORD variable As Long 结果为 Long 类型的表达式 . s2 v2 m4 \9 r% ?$ g9 V! n
LPINT, LPUINT variable As Long 结果为 Long 类型的表达式
0 ?) @3 p" O% Z) I9 K7 F( ]* dLPRECT variable As type 自定义类型的任意变量 ( B4 b8 z; l6 q$ X
LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式 , \. ^( L9 {( u# ?
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
/ L' w6 }3 V& k7 y6 e( X |LPWORD variable As Integer 结果为Integer 类型的表达式 8 J5 K- @1 y4 B, L3 o
LRESULT ByVal variable As Long 结果为 Long 类型的表达式
. d, e0 \' N9 l$ CNULL As Any 或 ByVal Nothing 或 ByVal variable As Long ByVal 0& 或 VBNullString SHORT ByVal variable As Integer 结果为Integer 类型的表达式
: H: O: e, Y$ O& h" w1 C9 UVOID Sub procedure 不可用
/ C& E1 ^- H+ S' @4 G2 Q V5 s0 |WORD ByVal variable As Integer 结果为Integer 类型的表达式 $ C e" [1 d. V7 u8 i; u
WPARAM ByVal variable As Long! A: \8 @# n+ i6 ?
, {2 o. O# s" z) X
|
|