如下 :
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 BooleanPublic 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对话框 但接着 程序运行终止刮掉 我估计是参数传递的问题 有什么解决发子
这样申明和delphi中的一样么?
Const p_OnFileArrive:TOnFileArrive):Boolean;stdcall;
为什么传参要用Const???
声明改为:
TOnFileArrive = Procedure(const p_FileName: PChar); safecall;原因就是调用协议不一样啊.
如果要通过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中使用了。
而我只能在vb中写为string型 老是说调用约定错误
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.
vbOption 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 SubPublic Function gcb(Myint As String) As Integer
Form1.Label1.Caption = "测试程序而已"
End Function
测试通过
应该改为:
public function gcb(byval myint as string) as integer
Function Listen (ListenPort:integer):boolean; stdcall; external 'JustPipe.Dll';
Function SetOnFileArrive(Const p_Port :Integer;
Const p_OnFileArrive:TOnFileArrive):Boolean; stdcall; external 'JustPipe.Dll';
TOnFileArrive=Procedure(Const p_FileName:PChar):Integer; stdcall;vb中我个人写的声明及回调函数
Declare Function Listen Lib "JustPipe" (ByVal port As Integer) As Boolean
Declare Function SetOnFileArrive Lib "JustPipe" (ByVal port As Integer, ByRef d As Long) As Boolean
//下面函数是调用dll中的SetOnFileArrive函数 以及传递我的回调函数的地址
Public Sub Hook()
Listen 2000
a = SetOnFileArrive(2000, AddressOf gcb)End Sub
End Sub
回调函数如下:
Public Sub gcb(ByVal filename As String)
MsgBox "ok"
End Sub为啥我老是调用不成功呢 什么地方出了问题?
的动态库, 只有做 ActiveX 的 COM, 而 COM 的调用协议为 safecall.若想在 Delphi 开发的程序中去调用 VB 的函数指针, 那么在 Delphi 中
声明的回调函数一定要为 safecall, 而且参数用 OleVariant 类型.
uses
SysUtils,
Classes;{$R *.res}
type
TOnFileArrive =procedure(MyChar:widestring);stdcall;
var
TempCallbackProc:TOnFileArrive;
function setOnFileArrive( p_Port :pchar; p_OnFileArrive: pointer):boolean; stdcall;export;
begin
@TempCallbackProc:=p_OnFileArrive;
if Assigned(TempCallbackProc) then
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("测试程序", AddressOf gcb)
If a Then
MsgBox "ok"
End If' lpPrevWndProc = SetWindowLong(Form1.hwnd, GWL_WNDPROC, AddressOf gcb)
End SubPublic Sub gcb(ByVal Mychar As String)
Form1.Text1.Text = Mychar
End Sub'需要注意参数的类型
vb中默认是byref
byref传递在delphi中应该用var ***来对应
如:
sub myTest(a as integer)
delphi中应该用procedure myTest(var a:longint);
function RFile_1(F_name:pchar):pchar;stdcall;export;VB的调用声明是这样写的:
Public Declare Function RFile_1 Lib "RFile.dll" (ByVal F_name As String) As String但是一调用,VB程序就会报内存错误后关闭.内存错误说****内存不能为读
RFile_1返回了pchar类型吗
function RFile_1(F_name:pchar):pchar;stdcall;export;
var
strTemp:string;
begin
strtemp:='测试';
result:=pchar(strtemp);
end;
var
F_buf,F_buf1:string;B_buf:array of byte;
F_hand,iFileLength,iBytesRead:integer;
i: Integer;
begin
Result := '';
F_buf:='';
try
F_hand:=fileopen(F_name,fmShareDenyWrite);
iFileLength := FileSeek(F_hand,0,2);
FileSeek(F_hand,0,0);
i:=iFileLength;
setlength(B_buf,i+1);
iBytesRead:=FileRead(F_hand,B_buf[0],iFileLength);
fileclose(F_hand);
for i := 0 to iFileLength-1 do
begin
F_buf1:=inttohex(B_buf[i],2);
F_buf:=F_buf+F_buf1;
end;
finally end;
RFile_1:=F_buf;
end;
函数原码
function RFile_1(F_name:pchar):String;stdcall;export;RFile_1:=F_buf;=>
RFile_1:=pchar(F_buf);
var
F_buf,F_buf1:string;B_buf:array of byte;
F_hand,iFileLength,iBytesRead:integer;
i: Integer;
begin
Result := '';
F_buf:='';
try
F_hand:=fileopen(F_name,fmShareDenyWrite);
iFileLength := FileSeek(F_hand,0,2);
FileSeek(F_hand,0,0);
i:=iFileLength;
setlength(B_buf,i+1);
iBytesRead:=FileRead(F_hand,B_buf[0],iFileLength);
fileclose(F_hand);
for i := 0 to iFileLength-1 do
begin
F_buf1:=inttohex(B_buf[i],2);
F_buf:=F_buf+F_buf1;
end;
finally end;
RFile_1:=pchar(F_buf);
end;
留下QQ,我发份源代码给你,我没发现问题
dll:
library Project1;{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Classes;{$R *.res}type
TOnFileArrive = procedure(MyChar:PChar);stdcall;
var
TempCallbackProc:TOnFileArrive;function SetOnFileArriveOfObj(p_Port :pchar; p_OnFileArrive: pointer):boolean; stdcall;export;
begin
@TempCallbackProc:=p_OnFileArrive;
if Assigned(TempCallbackProc) then
TempCallbackProc(p_Port); result:=true;
end;exports
SetOnFileArriveOfObj;begin
end.
vb:Private Sub Command1_Click()
Dim a As Boolean a = SetOnFileArriveOfObj(2000, AddressOf gcb)
If a Then
MsgBox "ok"
End If
End Sub
Public Declare Function SetOnFileArriveOfObj Lib ".\Project1" (ByVal port As String, ByVal b As Long) As Boolean
'回调函数为
Public Sub gcb(ByVal fillname As String)
MsgBox fillname
End Sub
有没有办法能解决啊!我另外开贴加高分求教!
F_buf,F_buf1:string;=>var
F_buf,F_buf1:widestring;
您好:
能否加我qq 250462434 我想请教您一下