如下 :
Function SetOnFileArrive(Const p_Port :Integer;
Const p_OnFileArrive:TOnFileArrive):Boolean; stdcall; external JustPipe.Dll;
以上是delqhi中的函数
TOnFileArrive =Procedure(Const p_FileName:PChar);
以上是delqhi中的需要回调的函数
我在vb中是这样做的
Declare Function SetOnFileArriveOfObj Lib "JustPipe" (ByVal port As Integer, ByVal b As Long) As Boolean
Public Sub Hook()
a = SetOnFileArriveOfObj(2000, AddressOf gcb)
If a Then
MsgBox "ok"
End If
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf gcb)
End Sub
回调函数为
Public Sub gcb(ByRef fillname() As Byte)
MsgBox fillname
End Sub
现在的问题是 回调已经成功 并弹出ok对话框 但接着 程序运行终止刮掉
我估计是参数传递的问题 有什么解决发子
关注...
等待高手
up
真是没看懂,不知道楼主想干嘛
Declare Function SetOnFileArriveOfObj Lib "JustPipe" (ByVal port As Integer, ByVal b As Long) As Boolean
这样申明和delphi中的一样么?
D:TOnFileArrive-->VB:Long???
Function SetOnFileArrive(Const p_Port :Integer;
Const p_OnFileArrive:TOnFileArrive):Boolean;stdcall;
为什么传参要用Const???
在 Delphi 中把 TOnFileArrive =Procedure(Const p_FileName:PChar);
声明改为:
TOnFileArrive = Procedure(const p_FileName: PChar); safecall;
原因就是调用协议不一样啊.
delphi中的pchar,vb中应该是用string
VB要调用Delphi程序只能通过DLL、ActiveX Control和ActiveX DLL来完成。你不能直接在VB中链接Delphi的.obj或.dcu文件。
如果要通过DLL,在Delphi中生成一个DLL项目,然后加入函数,注意每个函数都必须是stdcall方式的,如:
procedure OutportD(PortNum:word; Data:longint); stdcall;
然后在exports部分加上函数说明,如:
exports
OutportD index 9;
这样你就可以在VB中使用Declare语句调用DLL中的函数了。
建立ActiveX Control或ActiveX DLL,都需要建立一个ActiveX Library。如果是ActiveX Control,再加入ActiveX Control。如果是ActiveX DLL,加入Automation Object。在VB中调用ActiveX Control很简单。如果使用ActiveX DLL,只需要在Reference中加入.dll文件就可以在VB中使用了。
uses
SysUtils,
Classes;
{$R *.res}
type
TOnFileArrive =function(MyChar:pChar): longint;stdcall;
var
TempCallbackProc:TOnFileArrive;
function setOnFileArrive(Const p_Port :pchar; p_OnFileArrive: pointer):boolean; stdcall;export;
var
i:integer;
begin
@TempCallbackProc:=p_OnFileArrive;
if Assigned(TempCallbackProc) then
i:=TempCallbackProc(p_Port);
result:=true;
end;
exports
setOnFileArrive;
begin
end.
vb
Option Explicit
Public Const GWL_WNDPROC = (-4)
Declare Function setOnFileArrive Lib "Project1.dll" (ByVal port As String, ByVal b As Long) As Boolean
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Dim lpPrevWndProc As Long
Public Sub Hook()
Dim a As Boolean
a = setOnFileArrive(2000, AddressOf gcb)
If a Then
MsgBox "ok"
End If
lpPrevWndProc = SetWindowLong(Form1.hwnd, GWL_WNDPROC, AddressOf gcb)
End Sub
Public Function gcb(Myint As String) As Integer
Form1.Label1.Caption = "测试程序而已"
End Function
测试通过
用 VB 写的函数没有 stdcall 调用协议, 默认是 safecall 调用协议.
用 VB 写的函数做回调是会有问题的, 也就是说 VB 无法开发 API 函数
的动态库, 只有做 ActiveX 的 COM, 而 COM 的调用协议为 safecall.
若想在 Delphi 开发的程序中去调用 VB 的函数指针, 那么在 Delphi 中
声明的回调函数一定要为 safecall, 而且参数用 OleVariant 类型.