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

我了解到,您可以:

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

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

Solutions Collecting From Web of "使用DEF文件而不是LIB文件链接到DLL?"

归根结底,这里的答案是“因为没有人想要它太糟糕了,它并没有真正帮助任何东西”。

DEF文件是一个为DLL创建一个导入库的输入文件。 然后,后来,当DLL被另一个链接所占用时,importlib本身就是一个输入。 importlib在外面看起来像是特别的东西,但是当你看到里面的时候,它实际上只是一个稍微有些特殊的对象。

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

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

除此之外,这将是毫无意义的 – 允许链接器采取DEF文件或DLL作为输入既不会启用任何重要的新情况,也不会离开此功能阻止任何东西。 把你有的DEF文件(甚至没有实际的DLL)转换成一个可用的importlib是一小会儿的工作(简单地为每个DEF条目创建一个假的空函数并链接它)。 所以没有必要添加直接链接DEF文件的功能。

马丁

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

从文档 :

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

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

创建模块定义(.def)文件并在构建DLL时使用.def文件。 如果要按顺序而不是按名称从DLL中导出函数,请使用此方法。

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

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

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

我觉得你投下了票,因为你的观点不是很清楚,至少不是我。 也检查这一点 。 它解释了如何选择导出方法。

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

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

.def文件只是在创建.dll文件时用作“设置”或“配置”文件来指定文件应导出的功能。 它不能链接到,因为它没有真正描述链接器可以理解的任何东西。

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

当然,这是很难完成的,就好像你正在使用一个DLL来完成某些工作,通常你有这个权限,作者提供了.lib的头文件和二进制DLL文件。

我从来没有做过你说的确切的技术,通过转换.DEF信息a .LIB,等等..但是,我想这将是很容易采取一个库,或DLL本身,并从中导出。 现在,我已经做了一个项目,在这个项目中,DLL代码是使用从主项目获取代码的vbScript构建的,并且在所有现有的,编译和测试的代码中创建了一个API。 这个级别的复杂性只能这样做,因为我不知道DLL中的函数是什么,因为主项目随时都可能改变,所以一个静态的.DEF文件将无法工作。 所以,我必须构建一次DLL,捕获dimpbin /exportsdimpbin /exports函数,然后生成.DEF文件,然后重新链接DLL。

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

至于.LIB文件,通常你只需要那些用于静态链接的,但是当.H文件可用的时候,它们也被使用,通常使调试更好一些。