使用 DEF 文件而不是 LIB 文件链接到 DLL?

发布于 2024-11-25 01:29:53 字数 248 浏览 1 评论 0原文

我了解到您可以:

  • 将 .DLL 文件转换为 .DEF 文件,其中包括其导出
    (编辑:这不适用于许多约定)
  • .DEF 文件转换为 .LIB 文件,您可以使用该文件链接到 DLL

为什么(大多数)链接器不能链接到DLL 给出一个 .DEF 文件,而不是一个 .LIB 文件?

I have learned that you can:

  • Convert a .DLL file into a .DEF file, which includes its exports
    (Edit: This doesn't work with many conventions)
  • Convert a .DEF file into a .LIB file, which you can use to link to the DLL

Why can't (most) linkers link to a DLL given only a .DEF file, instead of a .LIB file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蛮可爱 2024-12-02 01:29:53

最终,这里的答案是“因为没有人非常想要它,而且它并没有真正帮助任何东西”。

DEF 文件是一个输入文件,为 DLL 创建导入库。然后,当 DLL 被另一个链接使用时,importlib 本身就是一个输入。 importlib 从外面看起来很特别,但是当你看内部时,它实际上只是一个稍微特殊的库,里面有对象。

完全可以修改链接器以直接获取 def 文件(或 DLL)。

但链接器的设计中心是它以对象作为输入并输出 PE 可执行文件。因此,将 DEF 或 DLL 作为输入超出了设计模式。

除此之外,这是毫无意义的 - 允许链接器将 DEF 文件或 DLL 作为输入既不会启用任何重要的新场景,也不会忽略此功能阻止任何内容。将您拥有的 DEF 文件(即使没有实际的 DLL)转换为可用的导入库只需几分钟的工作(只需为每个 DEF 条目创建假空函数并链接它)。因此没有理由添加直接链接 DEF 文件的功能。

马丁

Ultimately, the answer here is 'because noone wanted it badly enough and it doesn't really help anything'.

The DEF file is an input file that creates an import lib for the DLL. And then, later, when the DLL is being consumed by another link, the importlib is itself an input. The importlib looks like something special on the outside, but when you look at the inside it's really just a slightly special lib with objects in it.

It totally would be possible to modify the linker to take a def file (or a DLL, for that matter) directly.

But the design centre of the linker is that it takes objects as inputs and outputs a PE executable. So taking a DEF or DLL as an input goes outside the design pattern.

Beyond that it'd be rather pointless - allowing the linker to take a DEF file or DLL as input would neither enable any important new scenarios, nor does leaving this feature out block anything. Converting a DEF file you have (even without the actual DLL) into a usable importlib is the work of a few moments (simply create fake empty function for each DEF entry and link that). So there's no reason to add the ability to link a DEF file directly.

Martyn

素年丶 2024-12-02 01:29:53

就MSVC而言,.lib文件始终是静态库。它们作为编译单元与所有编译的 .c/.cpp 文件一起链接,因此所有库的代码都包含在最终的可执行文件中。

然而,一些 .lib 文件(特别是大多数 Windows 系统文件)仅包含存根,这些存根告诉操作系统在加载时加载所需的 DLL,然后存根将函数调用路由到 DLL。但是,这些存根静态链接到您的可执行文件中。然后,您的程序将使用 DLL(并获得其所有优点和缺点),但由于它所需的命名 DLL 函数很高兴位于 .lib 中(因此实际上位于可执行文件本身中),因此您的代码不必知道它正在使用 DLL(特别是使用 declspec(dllimport))。

.def 文件仅在创建 .dll 期间用作一种“设置”或“配置”文件,以指定文件应导出哪些函数。它无法链接到,因为它并没有真正描述链接器理解的任何内容。

In terms of MSVC, .lib files are always static libraries. They get linked in as a compilation unit along with all your compiled .c/.cpp files, so all of the library's code is included in your final executable.

Some .lib files, however, (in particular most of the Windows system ones) merely contain stubs which tell the OS to load the desired DLL at loadtime and then the stubs route function calls to the DLL. But, those stubs are statically linked into your executable. Your program will then use DLLs (and gain all the advantages and disadvantages thereof), but since the named DLL functions it requires are happily located in the .lib (and thus actually located in the executable itself), your code doesn't have to know it's using a DLL (specifically using declspec(dllimport)).

A .def file is merely used as a sort of "settings" or "configuration" file during the creation of a .dll to specify what functions the file should export. It cannot be linked to, as it doesn't really describe anything that the linker understands.

旧伤慢歌 2024-12-02 01:29:53

您不将 dll 转换为 DEF 文件。 DEF 只是指示哪些 dll 函数可以从外部访问、导出。

来自文档

<块引用>

DLL 文件的布局与 .exe 文件非常相似,其中一个
重要区别 — DLL 文件包含导出表。这
导出表包含 DLL 导出的每个函数的名称
到其他可执行文件。这些函数是进入
动态链接库;只有exports表中的函数可以被其他人访问
可执行文件。 DLL 中的任何其他函数都是该 DLL 私有的。
可以使用DUMPBIN工具查看DLL的导出表
使用 /EXPORTS 选项。

您可以使用两种方法从 DLL 导出函数:

创建模块定义 (.def) 文件并在以下情况下使用 .def 文件:
构建 DLL。如果您想导出函数,请使用此方法
从您的 DLL 中按序号而不是按名称。

在函数定义中使用关键字 __declspec(dllexport)。

使用任一方法导出函数时,请确保使用
__stdcall 调用约定。

使用提供的链接了解有关从 dll 导出的更多信息。

我认为你被否决是因为你的观点不太清楚,至少对我来说不是。另请检查。它解释了如何选择导出方法。

You do not convert a dll to a DEF file. The DEF just indicates which dll functions will be accessible from the outside, exported.

From the docs:

A DLL file has a layout very similar to an .exe file, with one
important difference — a DLL file contains an exports table. The
exports table contains the name of every function that the DLL exports
to other executables. These functions are the entry points into the
DLL; only the functions in the exports table can be accessed by other
executables. Any other functions in the DLL are private to the DLL.
The exports table of a DLL can be viewed by using the DUMPBIN tool
with the /EXPORTS option.

You can export functions from a DLL using two methods:

Create a module definition (.def) file and use the .def file when
building the DLL. Use this approach if you want to export functions
from your DLL by ordinal rather than by name.

Use the keyword __declspec(dllexport) in the function's definition.

When exporting functions with either method, make sure to use the
__stdcall calling convention.

Use the provided link to learn more about exporting from your dll's.

I think you got down voted because your point is not really clear, at least not to me. Also check this. It explains how to choose the export method.

哎呦我呸! 2024-12-02 01:29:53

Mehrdad,这并不总是如何链接到 DLL 的问题,因为我个人从未使用 .DEF 文件链接过 DLL。我所做的就是采用别人的 DLL,并非常煞费苦心地构建了一个头文件,或者更确切地说,构建了我可以使用的函数原型
C 中的 LoadLibrary(),VB 中的 声明函数 ... Lib“Foo.dll”别名“OrdinalName”,以及
C# 中的[DllImport()]

当然,这种情况很少发生,就好像您使用 DLL 来做某事一样,通常您有这样做的权限,并且作者提供了 .lib 以及二进制 DLL 文件的标头。

我从来没有做过你所说的确切技术,通过将 .DEF 信息转换为 .LIB 等...但是,我认为获取 lib 或 DLL 本身并从中导出 .DEF 会很容易。现在,我实际上已经完成了,在一个项目中,DLL 代码是使用 vbScript 构建的,该 vbScript 从主项目中获取代码,并从所有现有的、编译的和测试的代码中创建了一个 API 。这种程度的复杂性只是因为我不知道 DLL 中将包含哪些函数,因为主项目可能随时更改,因此静态 .DEF 文件永远不会工作。因此,我必须构建一次 DLL,捕获 dimpbin /exports,取消修饰函数,然后构建 .DEF 文件,并重新链接 DLL。

如果您发现自己处于这种情况,也许您需要重新思考您的原始设计,并从那里解决问题...

至于 .LIB 文件,通常您只需要那些用于静态链接,但当 .H 文件可用时也会使用它们,通常使调试变得更好一点......

Mehrdad, this isn't always a question of how to LINK to a DLL, as I, personally have NEVER linked a DLL using a .DEF file. What I HAVE done is take someone else's DLL, and very painstakingly constructed a header file, or rather, function prototypes that I could use with
LoadLibrary() in C, Declare Function ... Lib "Foo.dll" Alias "OrdinalName" in VB, and
[DllImport()] in C#.

Of course, this is RARELY done, as if you are using a DLL for something, normally you have permission to do so, and the authors provide the .lib's, and the headers to go with the binary DLL file.

I've never done the exact techniques you speak of, by converting a .DEF info a .LIB, etc... But, I suppose it would be easy to take a lib, or the DLL itself and export .DEF from it. Now, THAT I actually HAVE done, in a project where the DLL code was built with a vbScript that took code from the main project, and created an API out of all the existing, compiled, and tested code. This level of complication was only done because I had no idea what functions were going to BE in the DLL, as the main project could change at any time, so a static .DEF file would have never worked. So, I had to build the DLL once, capture the dimpbin /exports, undecorate the functions, and then build the .DEF file, and re-link the DLL.

If you find yourself in that type of situation, perhaps you need to re-think your original designs, and fix the problem from there...

As for .LIB files, USUALLY you'd only NEED those for static linkage, but they are also used when the .H file is available, often making debugging a just a little nicer...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文