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的主要内容,如果未能解决你的问题,请参考以下文章

使用Delphi创建的DLL在其他Delphi版本中运行良好,应该遵循哪些原则?

VS2017写的exe调用Delphi 7写的DLL

Delphi采用接口实现DLL调用

delphi 如何用ssleay32.dll

delphi调用vc编写的dll,出现错误

Delphi在创建和使用DLL的时候如果使用到string,请引入ShareMem单元