gpt4 book ai didi

delphi - 从 Delphi DLL 导出全局符号

转载 作者:行者123 更新时间:2023-12-03 14:40:00 25 4
gpt4 key购买 nike

我正在尝试在 Delphi 中创建一个与 Gecko 2.0 兼容的 DLL。

以前(Gecko 2.0 之前)DLL 需要导出 NSGetModule() 函数。这工作完美无缺。

从 Firefox 4 开始,我的 DLL 正在加载(我已经通过初始化部分中的断点验证了这一点),但我的 NSGetModule() 函数不再被调用。这是设计的行为,因为从 Gecko 2.0 (Firefox 4) 开始,二进制组件不应该导出 NSGetModule() 函数:

https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0#Binary_components

根据这些文档,我的 DLL 需要导出一个指向结构的 NSModule 数据符号。在Delphi术语中,我假设这是一个指向Delphi记录的全局变量。

在 C++ 中,这是导出(全局)数据符号的方式:

define NSMODULE_DEFN(_name) extern "C" NS_EXPORT mozilla::Module const *const NSModule

我的问题:如何在 Delphi 中实现这一点?如何导出全局变量?

感谢您的反馈。

最佳答案

Delphi 从 DLL 中导出全局变量的方式与导出函数的方式类似:

library exp;
var
global: Integer;
exports global;
end.

Delphi 可以从 DLL 导入全局变量,但这有点麻烦:声明一个与要导入的全局同名的 DLL 导入过程,然后获取该过程的地址并适当调整它。从Delphi 的角度来看,DLL 导入过程是通过DLL 导入表进行间接跳转的 stub 。导出的变量由操作系统加载器通过将导出的全局地址放入导入表来链接,几乎与导出过程的地址的修补方式完全相同。

例如:

{$apptype console}

procedure global; external 'exp.dll';

function GetGlobalAddr: PInteger;
type
PPPointer = ^PPointer;
var
p: PByte;
begin
p := @global;
Assert(p^ = $FF); // $FF $25 => indirect jump m32
Inc(p);
Assert(p^ = $25);
Inc(p);
Result := PPPointer(p)^^
end;

begin
Writeln(GetGlobalAddr^);
end.

当然,后面的细节取决于实现和平台等。可能更安全的方法是将 LoadLibraryGetProcAddress 一起使用,它将返回全局变量的地址当它的名字通过时。当然,这也依赖于平台。

64 位更新:

在 Windows 上的 64 位中,代码略有不同。操作码相同,但同一指令序列的寻址方式不同;它不是 32 位绝对偏移,而是 32 位相对偏移。

function GetGlobalAddr: PInteger;
type
PPPointer = ^PPointer;
var
p: PByte;
ofs: Integer;
begin
p := @global;
Assert(p^ = $FF); // $FF $25 => indirect jump m32
Inc(p);
Assert(p^ = $25);
Inc(p);
// 32-bit offset follows
ofs := PInteger(p)^;
// offset is relative to next instruction
Inc(p, SizeOf(ofs) + ofs);
Result := PPPointer(p)^^
end;

关于delphi - 从 Delphi DLL 导出全局符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3641983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com