Delphi DLL 和 Delphi EXE 之间的回调功能
Posted
技术标签:
【中文标题】Delphi DLL 和 Delphi EXE 之间的回调功能【英文标题】:Callback functionality between Delphi DLL and Delphi EXE 【发布时间】:2013-08-22 11:18:34 【问题描述】:我正在编写一个 Delphi DLL。在Delphi DLL中我想实现一个回调函数,这个回调函数应该回调给调用者Delphi程序。回调函数的主要目的是在DLL中会发生某些长时间的操作,但进度报告(通过进度条)和操作取消应该发生在调用者Delphi程序中。
我想获得一些关于如何在 DLL 中正确实现回调函数的支持。我可以继续分配从 EXE 传递的回调函数,但我不知道如何从 DLL 本身发起调用。
这是定义部分(EXE和DLL使用):
uses Windows;
Type
PTCallBackStruct = ^TCallBackStruct;
TCallBackStruct = packed record
Handle: THandle;
Caller: Pointer;
FileSize: LongInt;
end;
type
TFunctionPointerType = function(ZCallbackRec: PTCallBackStruct): Longbool;
stdcall;
type
PTDLLParamaters = ^TDLLParamaters;
TDLLParamaters = packed record
Handle: THandle;
Caller: Pointer;
CallbackFunction: TFunctionPointerType;
end;
var
DLLCallback: TFunctionPointerType;
EXE 文件:
uses ....
type
function DLL_Callback(ZCallBackRec: PTCallBackStruct): LongBool; stdcall;
forward;
implementation
function DLL_Callback(ZCallBackRec: PTCallBackStruct): LongBool; stdcall;
begin
// progress reporting this function should be called back from
//the DLL. The Handle and Self parameter should help with identifying
// which object initiated the callback
end;
通过 PTDLLParameters 从 Delphi exe 传递给 DLL 如下:
// init callback
DLLParameters := AllocMem(SizeOf(TDLLParamaters));
with DLLParameters^ do
begin
Handle := Application.Handle;
Caller := Self;
CallbackFunction:= DLL_Callback;
end;
加载 DLL
.....
.....
调用 DLL
CompressionCreateLibrary(DLLParameters);
....
某些操作
Free DLL
....
.....
FreeMem(DLLParameters);
DLL 文件:
这个函数应该从 DLL 的某些部分调用,使实际操作的进度返回到 EXE:
function CallCallBackFromDLL(Size: integer): Integer;
begin
//
....
set up callbackstruct
....
// calling back
DLLCallback(CallbackStruct);
end;
我觉得这部分应该没问题:
// main init call assigning the callback function to the DLL
function CompressionCreateLibrary(DLLParametersID: PTDLLParamaters): Integer;
begin
DLLParametersID.CallbackFunction:= @DLLCallback;
end;
请帮助我如何在 DLL 中正确实现回调部分。一些示例代码将不胜感激。虽然调试初始化工作正常,但进行回调失败。提前谢谢你。
【问题讨论】:
我不知道你在问什么。有相当多的代码摘录很难拼凑在一起。然后“进行回调失败”。呃,失败是什么意思?你的调试告诉你什么。请告诉我你已经做了一些调试。其他cmets: 1.不要使用包装好的。 2.不要使用@来获取过程变量。 这是一个几乎的好问题。您展示了您的代码,并解释了每个位的用途。您没有包含不相关的代码,但您显示了所有重要的声明。您没有包含的关键内容是对问题的描述。 “失败”还不够好。实际发生了什么,您预计会发生什么? 更多cmets。不需要堆分配,使用堆栈中的变量。传递指向记录的指针很粗糙。记录类型的 const 参数肯定是你需要的。 亲爱的 Rob,亲爱的 David,感谢 cmets。我将尝试进一步解释。我想要一个用于处理 tstream 内容的 DLL,基本上是压缩和解压缩,DLL 应该向调用程序报告进度(处理的字节数),以便有这个报告我想使用回调函数。当我调用 CallCallBackFromDLL 时,它只会引发异常。 它不只是抛出异常。它抛出带有消息的特定类的异常。您没有告诉我们该信息的事实表明您忽略了它。不。学会理解它。并始终包含该信息。 【参考方案1】:你的赋值语句是落后的。在 DLL 函数中,DLLParametersID
保存有关回调的信息,但随后您将其覆盖为全局变量:
DLLParametersID.CallbackFunction:= @DLLCallback;
将这些交换到 assign DLLCallback
。
【讨论】:
如果我这样做,我会收到一个编译器错误(没有足够的实际参数) 我建议您尝试设置断点并单步执行您的代码,然后学习查看变量的值。如果您错过了分配的方向,您可能会错过很多其他开发人员认为是显而易见的事情!如果您尝试单步操作,也许您可以看到代码运行时真正发生的情况。以上是关于Delphi DLL 和 Delphi EXE 之间的回调功能的主要内容,如果未能解决你的问题,请参考以下文章
在 Delphi 2007 DLL 和 XE6 EXE 之间传递 PChar
求教在delphi中,如何把一个exe做为res加入到dll中,并在运行时生成exe文件执行