Delphi - 创建具有转发导出函数的DLL

5
在C/C++中,可以创建一个DLL,在该DLL中将一些导出函数转发到其他DLL(而不使用存根加载器):
#pragma comment(linker, "/export:TestFunc=Real_Lib.dll.TestFunc")

或者,作为替代方案 - 使用.def文件:
EXPORTS
   TestFunc=c:/Real_Lib.dll.TestFunc

注意缺少参数或返回类型。

例如,对于kernel32.dllDependencyWalker中,您可以看到这个: KERNEL32.AddVectoredExceptionHandler => ntdll.AddVectoredExceptionHandler



问题: - 您能否在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.

转发 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.

这段代码可编译且可运行:结果为: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

那么,将一些仅限于C/C++的编译器魔法进行真正的转发是可能的吗?或者在Delphi中也可以实现吗?

这并不是 C 或 C++ 的特性,但很可能是 Microsoft 编译器的特性。我怀疑 Delphi 不能做到同样的事情。 - Rudy Velthuis
最终我将它分成了两部分:
  1. DLL with Exports forwarders = C++ (VS),其中还有自定义函数作为存根,动态加载并调用第二部分的函数;
  2. Delphi中的DLL - 提供自定义函数。
    当然,将第二部分实现在Delphi中只是为了节省时间。
- megamurmulis
1个回答

1

Delphi无法创建这样的可执行文件。如果您想从Delphi创建这样的DLL,则需要进行一些后处理。


Delphi不支持这个,但是C++Builder支持使用.def文件来声明EXPORTS,虽然我不知道它是否支持转发。 - Remy Lebeau
是的。而且MSVC支持转发导出。 - David Heffernan
你能澄清一下你所说的“后处理”是什么意思吗?~也许是将Delphi代码编译为.obj,然后将其提供给MS构建工具? - megamurmulis
不,我的意思是修改可执行文件并在元数据中重新编写PE导出表。你可能需要自己编写工具。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接