我了解到你可以:
为什么(大多数)链接器不能链接到只有 .DEF文件而不是.LIB文件的DLL?
答案 0 :(得分:4)
最终,这里的答案是“因为没有人想要它足够严重而且它对任何事情都没有帮助”。
DEF文件是一个输入文件,用于为DLL创建导入库。然后,稍后,当DLL被另一个链接使用时,importlib本身就是一个输入。 importlib在外面看起来很特别,但是当你看到它里面时,它实际上只是一个带有对象的特殊lib。
完全可以修改链接器直接获取def文件(或DLL)。
但链接器的设计中心是它将对象作为输入并输出PE可执行文件。因此,将DEF或DLL作为输入超出了设计模式。
除此之外它是毫无意义的 - 允许链接器获取DEF文件或DLL作为输入既不会启用任何重要的新场景,也不会阻止此功能阻止任何事情。将您拥有的DEF文件(即使没有实际的DLL)转换为可用的importlib是一段时间的工作(只需为每个DEF条目和链接创建假空函数)。所以没有理由添加直接链接DEF文件的能力。
马丁
答案 1 :(得分:2)
您不会将dll转换为DEF文件。 DEF只是指出哪些dll函数可以从外部访问,导出。
来自docs:
DLL文件的布局与.exe文件非常相似,只有一个 重要区别 - DLL文件包含导出表。该 exports表包含DLL导出的每个函数的名称 到其他可执行文件。这些功能是进入的入口点 DLL;只有exports表中的函数才能被其他人访问 可执行文件。 DLL中的任何其他函数都是DLL专用的。 可以使用DUMPBIN工具查看DLL的导出表 使用/ EXPORTS选项。
您可以使用两种方法从DLL导出函数:
创建模块定义(.def)文件并在何时使用.def文件 构建DLL。如果要导出函数,请使用此方法 从您的DLL按顺序而不是按名称。
在函数定义中使用关键字__declspec(dllexport)。
使用任一方法导出函数时,请务必使用 __stdcall调用约定。
使用提供的链接了解有关从dll导出的详细信息。
我认为你投了票,因为你的观点并不是很清楚,至少对我来说不是这样。同时检查this。它解释了如何选择导出方法。
答案 2 :(得分:2)
就MSVC而言,.lib文件始终是静态库。它们作为编译单元与所有已编译的.c / .cpp文件链接在一起,因此所有库的代码都包含在最终的可执行文件中。
但是,某些.lib文件(特别是大多数Windows系统文件)只包含存根,它们告诉操作系统在加载时加载所需的DLL,然后存根将函数调用到DLL。但是,那些存根 静态链接到您的可执行文件中。然后你的程序将使用DLL(并获得它的所有优点和缺点),但由于命名的DLL函数它需要很好地位于.lib中(因此实际上位于可执行文件本身),你的代码不必知道它正在使用DLL(特别是使用declspec(dllimport))。.df文件仅在创建.dll期间用作一种“设置”或“配置”文件,以指定文件应导出的功能。它无法链接,因为它没有真正描述链接器理解的任何内容。
答案 3 :(得分:1)
Mehrdad,这并不总是如何链接到DLL的问题,因为我个人从来没有使用.DEF文件链接DLL。我已经做的是拿别人的DLL,并且非常精心地构建了一个头文件,或者更确切地说,我可以使用的函数原型
C中为LoadLibrary()
,VB中为Declare Function ... Lib "Foo.dll" Alias "OrdinalName"
,.
C#中的[DllImport()]
。
当然,这很简单,好像你正在使用DLL一样,通常你有权这样做,作者提供.lib,并且标题与二进制DLL文件一起使用。
我从未完成你所说的确切技术,通过转换.DEF信息a .LIB等...但是,我认为使用lib或DLL本身并导出.DEF会很容易从中。现在,我实际上已经完成了,在一个项目中,DLL代码是使用从主项目中获取代码的vbScript构建的,并从所有现有的,已编译和测试的代码中创建了一个API 。这种复杂程度只是因为我不知道DLL中会有什么功能,因为主项目可能随时发生变化,因此静态的.DEF文件从未起作用。因此,我必须构建DLL一次,捕获dimpbin /exports
,解开函数,然后构建.DEF文件,并重新链接DLL。
如果您发现自己处于这种情况,也许您需要重新考虑原始设计,并从那里解决问题......
对于.LIB文件,USUALLY你只需 NEED 那些用于静态链接的文件,但是当.H文件可用时它们也会被使用,通常会使调试变得更好......