我看到了这样的Qt源代码:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
哪个Q_CORE_EXPORT
宏定义如下:
define Q_DECL_IMPORT __declspec(dllimport)
那到底是__declspec(dllimport)
什么意思呢?
Answers:
__declspec
是Microsoft特定的属性,允许您指定存储类信息。
(Nitpicker的角:但是,许多其他编译器供应商(例如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现在支持它,但这主要是出于与Microsoft编译器兼容的原因。而且我不了解“特定于MS”与“特定于编译器”有何不同。微软编写了一个C ++编译器,许多人使用它。它随Visual Studio一起提供。
__declspec(dllimport)
是一个存储类说明符,它告诉编译器在外部DLL中定义了函数,对象或数据类型。
函数或对象或数据类型是从DLL中导出的,带有相应的__declspec(dllexport)
。
__declspec(dllexport)
告诉编译器通知链接器,这些符号需要放置在导出表中(编译.dll时)。编译与.dll链接的程序时,__declspec(dllimport)
告诉编译器产生一个rip-relative绝对寄存器-间接间接调用(链接器将填充为指向导入表的解析),而不是通常的rip-relative register-direct。对未定义函数的间接调用指令(由于无法修改指令,链接器将插入thunk的相对地址,然后创建thunk,在其中将rip-relative绝对寄存器-间接间接调用传递给thunk。导入表中的函数指针)。这是代码大小和速度优化。导入库.lib告诉链接器将导入哪些符号,并用作创建导入表和在.text段中创建任何必要的thunk的指南。
https://docs.microsoft.com/zh-CN/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/zh-CN/cpp / build / importing-data-using-declspec-dllimport?view = vs-2019 https://stackoverflow.com/a/4490536/7194773
这意味着函数的定义在动态库中。有关更多详细信息和示例,请参考文档。