C++ 使用.def文件的利弊

C++ 使用.def文件的利弊,c++,windows,dll,shared-libraries,declspec,C++,Windows,Dll,Shared Libraries,Declspec,我不明白这段话: 导出.def文件中的函数可以控制导出序号。将导出函数添加到DLL时,可以为其指定比任何其他导出函数更高的序号值。执行此操作时,使用隐式链接的应用程序不必与包含新函数的导入库重新链接。如果您正在设计一个供许多应用程序使用的DLL,这是非常方便的,因为您可以添加新的功能,并且还可以确保它在已经依赖它的应用程序中继续正常工作。例如,MFC DLL是使用.def文件构建的 为什么应用程序在使用.def文件的情况下不必与导入库重新链接,而在函数添加到dll的情况下不必使用_declspe

我不明白这段话:

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

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


cf

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


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

确定,如果您有.def文件,则可以使用它创建导入库

即对于MS VC++或GCC

编译器和链接器更喜欢自己的二进制格式导入库,通常彼此不兼容。当您的DLL是在C/C++上编写的,而您的程序是在Ada/FORTRAN/Object Pascal等其他语言上编写的,或者反之亦然时,这一点尤其重要。因此,可以使用.def文件创建兼容的导入库


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

必须使.def文件与代码保持同步几乎没有什么乐趣。如果您不必重命名导出,那么declspec是非常方便的。请记住,您仍然可以使用#pragma comment插入链接器的/export指令。我不知道这篇文章为什么如此关注序号导出,反正没有人使用它(除了MSFT)。在我看来,.def文件更重要的优点是,您可以通过非混合名称导出函数,这使得从其他语言链接DLL比用其他语言编写DLL更容易。@zett42我不明白,如果我们更新DLL,为什么我们必须重新编译我们的应用程序。共享库的主要目标不是不这样做吗?如果您只添加了一个新函数,而现有函数保持向后,则不必重新编译应用程序兼容的。我真的看不出这篇文章的重点,因为首先必须使用.def文件才能按顺序导出。使用
\uu declspec(dllexport)
默认情况下,函数以名称导出。我同意@zett42在一些测试之后,我可以将新导出的函数添加到我的dll中,我的exe仍在工作。但是人们仍然说你必须重新链接,我仍然不明白为什么我很确定导入库是为任何DLL创建的,不管作者是否使用.def文件导出。使用
\uuu declspec dllexport
导出函数应该会生成一个import.lib文件。def文件可以手动创建,也可以通过某些工具从DLL导入部分提取。如果您使用汇编创建了DLL,并且需要一个导入库才能在C中使用它,而不使用LoadLibrary,该怎么办?在DLL已经生成之后,.def文件有什么用途?是的,例如,使用GNU DLL工具,如impdef foobar.DLL>foobar.def,一旦恢复了.def文件,您将如何处理它?我想它可以让你创建一个兼容的插入式替换DLL…很好的答案!我认为dll的主要优点是我们可以在不接触主应用程序的情况下更改它们。所以事实并非如此,我们必须将应用程序与dll重新链接?这是软件开发人员通常使用的方法吗?当我们使用另一种方法declspec时,它是否也在引擎盖下使用基数?@Rain io,您可以更改已可用函数的实现,但是你不能添加更多的函数。谢谢,但是我不明白,在使用declspec进行了一些测试之后,我可以将新导出的函数添加到dll中,并且应用程序main仍然可以在没有新链接的情况下工作。有什么我忘了的吗?@Rain io它不一定能工作。序数可能会改变,也可能保持不变。你确定(某些来源?)我认为declspec使用函数命名来查找它们,你确定即使使用declspec也使用序数吗?我们可以从一个.def文件中创建一个导入库,在编译dll之后,我们可以手动创建这个文件。而这个.def只提到了函数名,没有提到数字,我们使用lib create来构建exe,它可以工作,exe find dll函数只使用名称。这就是为什么我有点困惑。(我不是落选者)