Windows和C++:extern和__declspec(dllimport)

32

extern__declspec(dllimport)之间有什么区别/关系?我发现有时需要同时使用它们,有时只需要其中一个。

我理解的对吗:

  1. extern用于静态链接库,
  2. __declspec(dllimport)用于DLL(动态链接库),
  3. 它们都为各自类型的链接提供了相同的功能,
  4. 当使用导入库(帮助与dll链接的小型.lib文件)时,需要同时使用两者。
1个回答

49

extern表示实体具有外部链接性,即在其翻译单元(C或CPP文件)之外可见。这意味着相应的符号将被放置在目标文件中,因此如果将该目标文件作为静态库的一部分,它也将可见。但是,仅使用extern并不意味着该符号一旦成为对象文件的一部分并加入到动态链接库(DLL)中,它也会可见。

__declspec(dllexport)表示如果将符号添加到DLL中,则应从DLL中导出该符号。它用于编译进入DLL的代码。

__declspec(dllimport)表示将从DLL中导入该符号。它用于编译使用DLL的代码。

因为通常在编译DLL本身以及将使用DLL的客户端代码时都使用相同的头文件,所以惯例上定义了一个宏,当编译DLL时解析为__declspec(dllexport),并且在编译客户端时解析为__declspec(dllimport),如下所示:

#if COMPILING_THE_DLL
    #define DLLEXTERN __declspec(dllexport)
#else
    #define DLLEXTERN __declspec(dllimport)
#endif

回答您的具体问题:

  1. 是的,对于静态库,只需要使用extern即可。
  2. 是的 - 声明也需要extern(在这里查看解释)。
  3. 不完全正确 - 请参见上文。
  4. 对于__declspec(dllimport),您不一定需要extern(请参见上面链接的解释),但由于通常会使用相同的头文件,因为在编译DLL时需要它,所以您已经在头文件中使用了extern

第四点:虚拟内联方法怎么处理?据我所知,它们需要“extern”;这实际上是我在https://dev59.com/FUzSa4cB1Zd3GeqPjAyW中发现的。 - liori
1
对于类,最可管理(也是最常见)的方法是声明整个类为__declspec(dllexport)。导出单个类成员更加复杂...例如请参考http://msdn.microsoft.com/en-us/library/81h27t8c%28VS.80%29.aspx。 - Martin B
2
MSVS 2005文档已经停用,'(在此处解释)'链接指向一些已停用的文档。是否有可能将该链接更新为更近期版本的MSVS的等效链接? - Jonathan Leffler
@JonathanLeffler,archive.org告诉我这是此页面的旧版本:https://learn.microsoft.com/en-us/cpp/cpp/definitions-and-declarations-cpp?view=vs-2019 - PeterT
@PeterT — 谢谢! - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接