VB6的使用方法
由于VB6只能使用__stdcall方式的函数,所以只有部分函数能被VB6所调用,
Public Declare Sub CopyMemory()Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Function lstrlen()Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Public Type testStruct
a As Byte
b As Long
c As Double
sz As String * 5
End Type
Public Type Temp
sz As String * 5
End Type
Public Declare Function Max_d()Function Max_d Lib "dlltest" (ByVal a As Double, ByVal b As Double) As Double
Public Declare Function Min()Function Min Lib "dlltest" Alias "?Min@@YGHHH@Z" (ByVal a As Long, ByVal b As Long) As Long
Public Declare Function UseStruct()Function UseStruct Lib "dlltest" (ByRef a As testStruct) As Long
Public Declare Function UseStruct2()Function UseStruct2 Lib "dlltest" (ByRef a As Any) As Long
Public Declare Function UserCallBackFunc()Function UserCallBackFunc Lib "dlltest" (ByVal s As String, ByVal f As Long) As Long
Function CallBack()Function CallBack(ByVal lp As Long) As Long
Dim L As Long
L = lstrlen(lp)
Dim s As String
s = String$(L + 1, vbNullChar)
CopyMemory s, lp, L
MsgBox s & " , " & Str$(L)
Debug.Print "CallBack", s
CallBack = 3
End Function
Sub Main()Sub Main()
Debug.Print Max_d(4, 5), Min(4, 6)
Dim a As testStruct
Debug.Print UseStruct(a)
Debug.Print Chr(a.a), a.b, a.c, a.sz
Dim buf(18) As Byte
Debug.Print "----------------"
Debug.Print UseStruct2(buf(0))
Dim t As Byte
CopyMemory t, buf(0), 1
Dim L As Long
CopyMemory L, buf(1), 4
Dim d As Double
CopyMemory d, buf(5), 8
Dim s As Temp
CopyMemory s, buf(13), 5
Debug.Print Chr(t), L, d, s.sz
Debug.Print UserCallBackFunc("_测试asdasd中文sdfasdf", AddressOf CallBack)
End Sub
VB版本需要注意的是lstrlen 的声明 参数不是String而是Long类型,这是因为如果是String的话VB会对参数进行改造,将字符串指针转化为String类型,而我这里不需要改变,就需要一个原始的Long类型的指针.所以就更改了API的函数声明.以适应我的需求
Delphi编写DLL
library dlltest;
uses
SysUtils,
Classes;
function Max(X, Y: Integer): Integer; cdecl;
begin
if X > Y then Max := X else Max := Y;
end;
function Min(X, Y: Integer): Integer;overload; stdcall;
begin
if X < Y then Min := X else Min := Y;
end;
function Min(X, Y: Double): Double;overload; cdecl;
begin
if X < Y then Min := X else Min := Y;
end;
function swap( var x: Integer; var y: Integer): Integer; cdecl;
var
z:integer;
begin
z := x;
x := y;
y := z;
result := 1;
end;
function Max_d(X, Y:Double):Double;stdcall;
begin
if X > Y then Max_d := X else Max_d := Y;
end;
type
testStruct = record
a:Char;
b: Integer;
c:Double;
sz: array[0..4] of char;
end;
function UseStruct( var x:testStruct): Integer;stdcall;
begin
x.a := 'a' ;
x.b := 20 ;
x.c := 1.234 ;
StrCopy( x.sz , PChar('abcd') );
UseStruct:=SizeOf(testStruct) ;
end;
{$A1}
type
testStruct2 = record
a:Char;
b: Integer;
c:Double;
sz: array[0..4] of char;
end;
{$A8}
function UseStruct2( var x:testStruct2): Integer;stdcall;
begin
x.a := 'a' ;
x.b := 20 ;
x.c := 1.234 ;
StrCopy( x.sz , PChar('abcd') );
UseStruct2 := SizeOf(testStruct2) ;
end;
type
CallBackFuncType = function(x:PChar): Integer;stdcall;
function UserCallBackFunc( lp:PChar ; F:CallBackFuncType ): Integer;stdcall;
begin
F( lp );
UserCallBackFunc:= StrLen( lp ) ;
end;
exports
Max,
Min(X, Y: Integer) name '?Min@@YGHHH@Z',//和C++导出的重载函数名字一样
Min(X, Y: Double)name '?Min@@YANNN@Z',
swap,
Max_d,
UseStruct,
UseStruct2,
UserCallBackFunc;
begin
end.Delphi导出的时候可以自由设置输出的名字,这样就可以写出来和C++写出来的DLL有相同的导出表.
也就是说可以和C++写的dll互相替换着调用.
关于VB编写DLL
由于VB6不容易编写类似功能的DLL的,主要是官方未支持.虽说有人发布相应的SDK.
但毕竟没有官方支持,应用也很难推广开来,所以在这里说明一下,也就不提供VB6编写这样的DLL的.
预计我会写一篇使用COM的方式实现多语言编程,到时候就可以看到VB6版的DLL.
总结一下
说来DLL要想能够在多种语言中都可以使用,那么就需要使用__stdcall方式调用(VB只支持这中方式),
以及都有的数据类型.这样就限定了,只能使用整形(1字节char,2字节short ,4字节long,8字节的long long),浮点型(4字节的float,8字节的double),以及指针类型(包括函数指针).精确的说只有CPU所支持的类型,才容易做到无障碍的通用.
小技巧
由于C/C++程序在使用静态载入DLL的方式的时候,需要lib文件参与链接,这个时候可以自己创建一个DLL
工程,然后导出原本DLL中的函数,函数实现为空就可以了,然后用这个lib参与链接,在调用你所要使用的DLL是可以的.
RSS订阅






收 藏
推 荐