这是为了将我的评论进一步扩展到大卫的回答:
DLL端:
- 在 DLL 中添加Init程序
- 导出它。
- 根据需要添加所需的类型/变量声明
片段代码:
library TheDLL;
...
var
OwnerAPP: HMODULE; // To be initialized by a call of the exported procedure Init from the EXE
...
type
TTestCallfromExe = procedure(f_Text: PAnsiChar); stdcall;
var
OwnerAPP: LongInt;
l_TestCallfromExe: TTestCallfromExe;
procedure Init(Owner: HMODULE);
begin
OwnerAPP := Owner;
end;
...
exports
Init, // This is it and the others exports follow
...
对TestCallfromExe的调用与通常调用任何 Dll 的导出函数/过程一样。只要OwnerAPP正确初始化,就可以根据 OP 的要求在 Dll 导出函数的主体中进行调用。
EXE端:
根据需要导出每个过程/函数(从 DLL 调用),当然您应该实现它们中的每一个。
program TheEXE;
uses
...
MyExportImplementation; // Refence to implementatio unit
...
exports
TestCallfromExe, // This is it
...
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
示例实现细节:
unit MyExportImplementation;
interface
...
procedure TestCallfromExe(f_Text: PAnsiChar); stdcall;
implementation
...
procedure TestCallfromExe(f_Text: PAnsiChar); stdcall;
begin
MessageBoxA(0, f_Text, 'Exe Dialog Ansi (stdcall)', 0);
end;
...
end.
把它们放在一起:
这是基于 DemoDLL(来自 BTMemory)示例,例如在TheEXE.dpr项目的 MainForm 单元中实现:
procedure TForm1.BtnCAllClick(Sender: TObject);
var
l_Init: procedure(Owner: HMODULE);
begin
m_DllHandle := LoadLibrary('TheDLL.dll');
try
if m_DllHandle = 0 then
Abort;
@l_Init := GetProcAddress(m_DllHandle, 'Init'); // <<<
if @l_Init = nil then
Abort;
// Fetch the remainding exported function(s)/procedure(s) adresses
l_Init(HInstance); // <<< Hand EXE's HInstance over to the DLL
// Call exported function(s)/procedure(s) accordingly
except
Showmessage('An error occured while loading the dll');
end;
if m_DllHandle <> 0 then
FreeLibrary(m_DllHandle)
end;
注意事项:
我也用 BTMemory 对其进行了测试,它可以工作。