Delphi - 使用转发导出创建 DLL
Posted
技术标签:
【中文标题】Delphi - 使用转发导出创建 DLL【英文标题】:Delphi - creating DLL with forwarded exports 【发布时间】:2015-10-10 14:15:51 【问题描述】:在 C/C++ 中,可以创建一个 DLL,其中一些导出函数被转发到其他一些 DLL(不使用存根加载器):
#pragma comment(linker, "/export:TestFunc=Real_Lib.dll.TestFunc")
或者替代 - 使用 .def 文件:
EXPORTS
TestFunc=c:/Real_Lib.dll.TestFunc
(注意缺少参数或返回类型)。
例如 - 在DependencyWalker
中为kernel32.dll
- 你可以看到:
问题: - 你能在 Delphi 中为 DLL 实现类似的结果吗? (必须使用 CLI 编译器是可以的..)
基本想法是生成仅重载某些函数并转发其余函数的 DLL 包装器 - 无需为所有导出的函数(带有参数、返回类型等)创建存根加载器。
注意: 我知道您实际上可以省略引用导入的导出函数的方法参数 = 重大改进.. 但仍然需要指定正确的方法类型(过程/函数)、返回类型(对于函数)和调用约定。
示例(TestProgram -> Forwarder -> Real_DLL):
真正的 DLL 文件 - 只是您的常规 dll:
library Real_Lib;
function TestFunc(a, b: Integer): Integer; stdcall;
begin
Result := a+b;
end;
exports TestFunc;
begin
end.
Forwarder DLL - 将导出的函数“转发”到静态导入:
library Forwarder;
function TestFunc: Integer; stdcall; external 'Real_Lib.dll';
exports TestFunc;
begin
end.
= 请注意可以安全地省略参数。 但是 - 仍然需要指定函数返回类型。
测试程序 - 使用转发器 DLL:
program TestProgram;
$APPTYPE CONSOLE
function TestFunc(a, b: Integer): Integer; stdcall; external 'Forwarder.dll';
begin
Writeln('Result: ', TestFunc(2, 7));
Readln;
end.
= 编译并运行:Result: 9
.
尽管DependencyWalker
将其显示为简单的调用导入函数的常规导出:
并生成这些操作码:
00403E82 . E8 7DFFFFFF CALL <JMP.&Forwarder.TestFunc>
00403E04 $- FF25 20614000 JMP DWORD PTR DS:[<&Forwarder.TestFunc>] ; Forwarde.TestFunc
00383810 F>- FF25 08613800 JMP DWORD PTR DS:[<&Real_Lib.TestFunc>] ; Real_Lib.TestFunc
那么 - 在 Delphi 中真的转发一些仅 C/C++ 的编译器魔法还是可能的?
【问题讨论】:
这并不是真正的 C 或 C++ 的特性,但它可能是 Microsoft 编译器的特性。我怀疑 Delphi 也能做到。 我最终将它分成两部分: 1. 带有导出转发器 = C++ (VS) 的 DLL,它还具有自定义函数作为存根动态加载和调用来自 #2 的函数; 2. Delphi中的DLL - 提供自定义功能。当然,在 Delphi 中实现 #2 只是为了节省时间.. 【参考方案1】:Delphi 无法创建这样的可执行文件。如果要从 Delphi 创建这样的 DLL,则需要执行一些后处理。
【讨论】:
Delphi不支持这个,但是C++Builder支持.def文件声明EXPORTS
,虽然不知道是否支持转发。
是的。并且 MSVC 支持转发导出。
你能解释一下你所说的“后处理”是什么意思吗? 〜也许将delphi代码编译为.obj,然后将其提供给MS构建工具?
没有。我的意思是修改可执行文件并在元数据中重写 PE 导出表。您可能需要自己编写工具。以上是关于Delphi - 使用转发导出创建 DLL的主要内容,如果未能解决你的问题,请参考以下文章