Delphi XE6 DLL: 不需要的导出:TMethodImplementationIntercept

13
在Delphi XE6中编译DLL时,会自动从System.Rtti.pas中导出函数TMethodImplementationIntercept。我试图寻找避免导出的方法,但没有找到任何配置或编译器指令可以解决这个问题。
由于System.Rtti单元几乎被Delphi中的所有组件间接使用,因此几乎不可能避免该单元。
在XE6中构建DLL时,有没有避免导出此功能的方法?

只是一个问题:为什么避免导出此函数很重要? - HeartWare
5
第一:在大多数情况下没用。第二:很奇怪。 - karliwson
@HEARTWARE 一个人喜欢整洁 - David Heffernan
@Kekas 这在 XE6 中是新的吗? - David Heffernan
@DavidHeffernan 我从XE2跳到XE6,所以我还不知道。 - karliwson
1个回答

9

System.Rtti单元中的代码如下:

{ This function has been added to be used from .s .c files in order to avoid use mangled names}
procedure TMethodImplementationIntercept(const obj:TMethodImplementation; AFrame: Pointer); cdecl;
begin
  obj.Intercept(AFrame);
end;
exports TMethodImplementationIntercept;

这个函数和exports指令在XE5中添加。

在XE6中构建DLL时有没有避免导出此函数的方法?

如果您的库包括System.Rtti单元,则DLL将导出该函数。如果要生成不导出该函数的DLL,可以考虑以下选项:

  1. 使用旧版Delphi。
  2. 不要在库中包含System.Rtti
  3. 使用未导出该函数的修改版System.Rtti
  4. 在生成DLL后修改它以从PE导出表中删除该函数。

我认为前两个选项不太理想。第三个选项似乎很有吸引力,但我认为可能难以实现。看起来这个老套路不再管用了。我还没有能够重新编译RTL单元并避免可怕的X was compiled with a different version of Y错误。

那么只剩下最后一个选项了。同样不是非常理想。您可能会决定接受这个意外的导出。也许一个QC报告可以对Embarcadero重新考虑这个决定施加一点压力。

就我个人而言,我认为任何编译器库代码都不应无条件导出函数。应该是库的使用者而不是实现者来做出这个决定。


我完全同意“编译器库代码永远不应无条件地导出函数”的观点。选项2对我来说不可能,因为正如我之前所说,RTTI被几乎所有东西间接使用。我已经有一个自动化构建系统正在使用我开发的工具进行第四个选项。当有时间时,我考虑尝试第三个选项,因为第四个选项似乎更像是一种hack方法。 - karliwson
3
自XE4开始(我想是这样),无法避免使用System.Rtti,因为它被System.Classes所使用。 - Stefan Glienke
1
@Stefan 虽然可以避免使用类(Class),但是不使用时剩下的就不多了。我看到XE6之后,越来越喜欢XE3。 - David Heffernan

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