class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
哪个 Q_CORE_EXPORT
宏定义的内容如下:
define Q_DECL_IMPORT __declspec(dllimport)
那么__declspec(dllimport)
到底是什么意思呢?
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
哪个 Q_CORE_EXPORT
宏定义的内容如下:
define Q_DECL_IMPORT __declspec(dllimport)
那么__declspec(dllimport)
到底是什么意思呢?
__declspec
是一个微软特有的属性,允许你指定存储类信息。
(挑剔者角落:然而,其他一些编译器供应商(例如GCC)现在为了与针对 Microsoft 编译器的代码进行兼容而支持此语言扩展。甚至提供了额外的存储类属性。)
其中可以指定的两个存储类属性是 dllimport
和 dllexport
。它们分别表示从 DLL 中导入或导出函数或对象。
更具体地说,它们定义了 DLL 的客户端接口,而不需要模块定义 (.DEF
) 文件。大多数人发现使用这些语言扩展比创建 DEF 文件要容易得多。
由于明显的原因,__declspec(dllimport)
和 __declspec(dllexport)
通常是配对使用的。你使用 dllexport
将符号标记为从 DLL 导出,并使用 dllimport
在另一个文件中导入该导出的符号。
由于这个原因,并且通常在编译 DLL 和使用 DLL 接口的客户端代码时都使用相同的头文件,所以定义一个宏,在编译时自动解析为适当的属性说明符是一种常见的模式。例如:
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
然后使用DLLEXPORT
标记应该被导出的所有符号。
可以假设Q_CORE_EXPORT
宏的作用是解析成Q_DECL_IMPORT
或者Q_DECL_EXPORT
。
__declspec
符号作为C++语言的扩展。我相信GCC现在也支持它,但这主要是为了与微软的编译器兼容。我不明白“MS-specific”和“compiler specific”有什么不同。微软编写了一个C++编译器,很多人使用它。它随同Visual Studio一起提供。 - Cody Gray__declspec()
和dllimport/dllexport
都不是专门针对微软编译器的。__declspec
被许多不同供应商的编译器用于支持C++语言本身的特定扩展。几乎所有支持微软平台的C++编译器都支持dllimport/dllexport
扩展,但它们绝不是唯一可用的扩展。 - Remy Lebeau__declspec(dllimport)
是存储类说明符,告诉编译器一个函数、对象或数据类型在外部DLL中定义。
使用对应的 __declspec(dllexport)
导出一个函数、对象或数据类型到DLL中。
__declspec(dllexport)
告诉编译器通知链接器需要将这些符号放在导出表中(在编译.dll时),并将这些符号放在导入库.lib中。当编译与.dll链接的程序时,__declspec(dllimport)
告诉编译器产生一个rip相对的内存间接调用(链接器将填充以指向导入表解析)而不是通常的相对直接指令到未定义函数(由于它不能修改指令,链接器插入thunk的相对地址,然后创建thunk,在其中放置rip相对的内存间接跳转到导入表中的函数指针)。这是代码大小和速度的优化。导入库.lib告诉链接器哪些符号由.dll导出,并用作基于这些符号与匹配的extern符号表条目的交集来创建导入表的指南,并在.text段中创建任何必要的thunk。
https://learn.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://learn.microsoft.com/en-us/cpp/build/importing-data-using-declspec-dllimport?view=vs-2019 https://dev59.com/Ym855IYBdhLWcg3wMBLV#4490536