【问题标题】:Pros and Cons of Using .def Files使用 .def 文件的优缺点
【发布时间】:2018-08-15 21:26:17
【问题描述】:

我不明白这一段:

在 .def 文件中导出函数可让您控制导出序数。将导出函数添加到 DLL 时,可以为其分配比任何其他导出函数更高的序数值。执行此操作时,使用隐式链接的应用程序不必重新链接到包含新函数的导入库。如果您正在设计一个供许多应用程序使用的 DLL,这将非常方便,因为您可以添加新功能并确保它继续与已经依赖它的应用程序一起正常工作。例如,MFC DLL 是使用 .def 文件生成的。

如果使用 .def 文件而不是 __declspec(dllexport) 在函数添加到 dll 的情况下,为什么应用程序不必重新链接导入库?

cfhttps://docs.microsoft.com/en-us/cpp/build/determining-which-exporting-method-to-use

【问题讨论】:

  • 必须让 .def 文件与您的代码保持同步并不是一件好事。如果您不必重命名导出,那么您永远不会真的这样做,那么 declspec 非常方便。请记住,您仍然可以使用 #pragma 注释来注入链接器的 /export 指令。
  • 我不知道为什么这篇文章如此专注于按序号导出,反正没人使用(除了 MSFT)。 IMO .def 文件更重要的优点是您可以通过未损坏的名称导出函数,这使得从其他语言链接 DLL 比编写它更容易。
  • @zett42 我不明白为什么如果我们更新一个 dll 就必须重新编译我们的应用程序不是共享库不必这样做的主要目标吗?
  • 如果您只添加新功能并且现有功能保持向后兼容,则无需重新构建应用程序。我真的不明白文章那部分的意义,因为您必须首先使用 .def 文件才能按序号导出。 __declspec(dllexport) 函数默认按名称导出。
  • 我同意@zett42 在一些测试后我可以将新的导出函数添加到我的 dll 和我的 exe 仍然工作。但是人们仍然说你必须重新链接我仍然不明白为什么

标签: c++ windows dll shared-libraries declspec


【解决方案1】:

这是因为共享对象(或 DLL)的 MSFT 实现的一些细节。在 Microsoft 世界中,为了将函数导入您的进程,您不仅需要共享代码本身 (.dll),还需要特殊的“导入”库 - .lib 文件。该文件静态链接到您的应用程序(因为它是一个静态库)。这个库在函数名和函数序号之间提供了“胶水”。

通常,每次发布新版本的 DLL 时,所有使用它的应用程序都必须重新链接到附带的新版本静态导入库 (.lib) 才能使用这个新的 DLL 库。这是因为创建新库后函数序号通常不再有效。但是,如果您使用 .def 文件,您可以手动分配序号,并确保序号对于以前可用的功能保持不变 - 因此 .lib 文件仍然有效。

【讨论】:

  • 很好的答案!我认为 dll 的主要优点是我们可以在不接触主应用程序的情况下更改它们。所以事实上我们不是必须用 dll 重新链接应用程序吗?是软件开发者常用的方法吗?当我们使用其他方法 declspec 时,它是否也在后台使用基数?
  • @Rain-io,你可以更改已有功能的实现,但不能添加更多功能。
  • 谢谢,但我不明白在使用 declspec 进行一些测试后,我可以将新的导出函数添加到 dll 中,并且应用程序主程序在没有新链接的情况下仍然可以工作。有什么我忘记了吗?
  • @Rain-io 不能保证正常工作。序数可能会改变,可能保持不变。
  • 你确定吗(一些来源?)我认为使用 declspec 它使用函数命名来查找它们,你确定即使使用 declspec 它也使用序数?我们可以从 .def 创建一个导入库,我们在编译 dll 后手动创建。而且这个.def只提到了函数名,没有提到编号,我们使用lib create来构建我们的exe并且它可以工作,exe找到只有名称的dll函数。这就是为什么我有点困惑。 (我不是反对者)
【解决方案2】:

好的,如果你有一个 .def 文件,你可以使用它来创建一个导入库。

mydll.lib 用于 MS VC++ 或 mylib-dll.a 用于 GCC

编译器和链接器更喜欢自己的二进制格式导入库,通常彼此不兼容。当您的 DLL 是用 C/C++ 编写的,但您的程序是用其他东西(如 Ada/FORTRAN/Object Pascal 等)编写时,这尤其重要,反之亦然。因此 .def 文件可用于创建兼容的导入库。

段落告诉您一种从导入库中隐藏某些函数的方法,通过手动编辑 .DEF 文件并指示链接器隐藏某些函数。

【讨论】:

  • 我相当肯定,无论作者是否使用 .def 文件进行导出,都会为任何 DLL 创建导入库。使用__declspec dllexport 导出函数应该也会生成一个导入.lib 文件。
  • .def 文件甚至可以手动创建或通过某些工具从 DLL 导入部分提取。如果您使用程序集创建了 DLL,并且需要一个导入库以便在没有 LoadLibrary 的情况下在 C 中使用它,该怎么办?
  • DLL已经建好后的.def文件有什么用?
  • 是的,例如使用 GNU DLL 工具 mirrors.zoreil.com/webclub.kcom.ne.jp/ma/colinp/win32/tools/… 像这样 impdef foobar.dll >foobar.def
  • 一旦你恢复了一个.def文件,你会用它做什么?我想它使您能够创建兼容的插入式替换 DLL...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2013-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多