【问题标题】:Why can I export the same function multiple times?为什么我可以多次导出同一个函数?
【发布时间】:2015-03-23 16:23:19
【问题描述】:

当我从库中多次导出过程ha 时:

library hahaha;

procedure ha; 
begin 
  Writeln('ha') 
end;

exports
  ha, ha, ha;    
end.

Delphi 巧妙地创建了一个包含三个过程的 .dll:

我很惊讶GetProcAddress(LoadLibrary('hahaha.dll'), 'ha') 的模棱两可的调用没有失败。

这让我想知道:这有什么用处吗?

【问题讨论】:

  • 为什么GetProcAddress() 会失败?它只是返回它找到的第一个具有匹配名称的函数,它不检查该名称是否重复多次。德尔福也不在乎。如您所见,每个导出的函数都有不同的序数值。 Delphi 只是用您告诉它导出的任何名称填充EXPORTS 表。
  • @RemyLebeau 我知道这非常愚蠢和挑剔,但实际上是否有消息来源指出 GetProcAddress 返回 first
  • @GünthertheBeautiful,它也可能返回 last(取决于导出表查找实现),但无论如何返回的地址都是正确的。
  • @Wouter,你为什么认为你的电话是模棱两可的?您要求 pointer by name 并且该函数根据其合同返回正确的结果。合约没有强制验证导出表中名称唯一性的功能。
  • @FreeConsulting:如果房间里有 3 个叫“John”的人,我让 John 给我 10 欧元,那么所有 Johns 都会说我含糊不清。跨度>

标签: delphi dll


【解决方案1】:

这很有用的一个地方是当您希望以不同的名称多次导出函数时。例如,如果我们尝试在 Delphi 中重新实现 user32,我们可能会导出如下:

exports
  SetWindowTextA,
  SetWindowTextA name 'SetWindowText';

在您的情况下,尽管您使用相同的名称和不同的序数值多次导出相同的函数。你为什么想这么做?我看不出想要这样做的充分理由。但是,为什么编译器要阻止你这样做呢?编译器开发人员需要付出努力才能做到这一点,会得到什么?

因此,我的猜测是编译器开发人员没有在多个具有相同名称的导出上实现块,因为:

  1. 他们没有考虑这种情况,或者
  2. 他们考虑并确定,阻止多个同名进口所涉及的努力无法提供足够的收益来证明开发成本的合理性。

至于调用GetProcAddress,函数名已经被多次导出,系统会返回第一个匹配的函数名。

【讨论】:

  • 我会在最后添加“这无论如何都不会产生影响,因为这些引用中的每一个都会路由到相同的函数。”
  • @JerryDodge:不,代码似乎是重复的,所以我会说它不是同一个函数,而是相同的功能:) 无论如何,如果编译器对此发出警告会很好.我现在交付了几个版本的 .dll,其中包含一些双重导出。
  • @WoutervanNifterick 是一样的功能。你只执行一次ha
猜你喜欢
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 2017-01-19
相关资源
最近更新 更多