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



我知道你可以:

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

为什么不能(大多数)链接器链接到DLL给只有一个。def文件,而不是一个。lib文件?

最终,这里的答案是'因为没有人非常想要它,它真的没有什么帮助'。

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

完全有可能修改链接器以直接接受def文件(或DLL,就此而言)。

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

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

Martyn

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

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

.def文件只是在创建.dll期间用作"设置"或"配置"文件,以指定文件应该导出哪些函数。它不能被链接到,因为它并没有真正描述链接器理解的任何内容。

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

From the docs:

DLL文件的布局与.exe文件非常相似,有一个重要的区别- DLL文件包含一个导出表。的exports表包含DLL导出的每个函数的名称到其他可执行文件。的入口点DLL;只有exports表中的函数可以被其他表访问可执行文件。DLL中的任何其他函数对DLL来说都是私有的。可以使用DUMPBIN工具查看DLL的导出表

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

创建一个模块定义(.def)文件,并在下列情况下使用.def文件构建DLL。如果要导出函数,请使用此方法按序号而不是按名称从DLL中删除。

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

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

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

我认为你被否决是因为你的观点不是很清楚,至少对我来说不是。再看看这个。它解释了如何选择导出方法。

Mehrdad,这并不总是一个如何链接到DLL的问题,因为我个人从来没有使用。def文件链接过DLL。我已经做的是取别人的DLL,非常辛苦地构造了一个头文件,或者更确切地说,是我可以使用的函数原型C中的LoadLibrary(), VB中的Declare Function ... Lib "Foo.dll" Alias "OrdinalName",和c#中的[DllImport()]

当然,这是很少做的,如果你正在使用一个DLL做某事,通常你有权限这样做,作者提供。lib's,和头与二进制DLL文件。

我从来没有做过你所说的确切技术,通过将。def转换为。lib等…但是,我想这将是很容易采取一个库,或DLL本身,并从它导出。def。现在,我实际上已经完成了,在一个项目中,DLL代码是用vbScript构建的,它从主项目中获取代码,并从所有现有的,编译的和测试的代码中创建了一个API。这种复杂程度只是因为我不知道DLL中会有什么函数,因为主项目随时都可能发生变化,所以静态. def文件永远不会起作用。因此,我必须构建一次DLL,捕获dimpbin /exports,取消函数,然后构建. def文件,并重新链接DLL。

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

对于.LIB文件,通常您只需要用于静态链接,但当.H文件可用时也使用,通常使调试变得更好…

最新更新