dllexport在标题混乱中

时间:2013-12-15 03:31:27

标签: dll linker

我很困惑为什么__declspec(dllexport)或等价物需要进入头文件。说我正在写一个图书馆。当然,用户不需要知道或担心符号是否被导出,他们关心的是函数声明是否存在,并且可能与共享或静态库本身相关联。那么为什么所有这些样板都不能进入源文件,只能在构建时使用?

我想到的唯一一个用例是有人正在编写我的库的包装器,并且需要导出我的所有函数,但一般情况并非如此 - 是否真的值得拥有麻烦公共标题内的所有导出内容?有没有我遗漏的东西,这是连接器的技术限制吗?

我问,因为我喜欢我的标题和构建系统是干净的,因为dllexport内容通常根据我们是否构建库来设置/不设置共享或静态库,我觉得很奇怪,它应该最终在公共标题内,因为它(根据我的理解)从根本上说是一个构建时间概念。那么有人可以告诉我我缺少的东西吗?

1 个答案:

答案 0 :(得分:1)

我不确定我能提供一个好的答案。我的印象是它有几个目的:

  1. 它加速了DLL的加载,特别是在使用大量DLL时(因为搜索的导出符号较少)
  2. 它减少了符号在运行时发生碰撞的可能性(因为导出的符号较少)
  3. 它允许链接器抱怨未定义的符号(而不是假设它可能在运行时找到它们。
  4. 我确定还有其他原因。我通常将我的API包装成这样的东西:

    #if defined(MY_LIB_CREATION)
        #define MY_LIB_API __declspec(dllexport)
    #else
        #define MY_LIB_API __declspec(dllimport)
    #endif
    

    然后我的所有API函数和&类被定义为MY_LIB_API:

    class MY_LIB_API Foo {};
    MY_LIB_API void bar();
    

    然后在项目文件中为实现库的项目定义了MY_LIB_CREATION。