DLL和静态库的相同头文件

时间:2009-07-07 00:25:54

标签: c++ windows

因此,定义DLL的导出/导入的常见(至少VS 2005状态)方式是:

#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif

class MY_API MyClass {
    ...
};

如果我只是将代码构建为DLL,那么这很有用。但是,我想选择使用静态库或DLL。现在一个明显(但可怕)的解决方案是复制所有代码,删除DLL'MY_API'定义。现在看起来更好的方法是命令行切换来定义或不定义DLL的东西。但是对于静态库,“MY_API”应该是什么?

#ifdef DLL_CONFIG
    #ifdef MY_EXPORTS
    #define MY_API __declspec(dllexport)
    #else
    #define MY_API __declspec(dllimport)
    #endif
#else
    #define MY_API // What goes here?
#endif

class MY_API MyClass {
    ...
};

现在假设可以这样做,当库的用户包含头文件时会出现问题(即他们是否必须定义'DLL_CONFIG')?

3 个答案:

答案 0 :(得分:12)

没有

将其保留为#define MY_API,MY_API的所有实例都将消失。

您可以添加新的构建配置,例如Debug - DLL和Release - DLL,它们模仿除#define DLL_CONFIG之外的其他配置。

要克隆配置,请转到配置管理器(如“调试/发布”列表框的下拉列表),然后在“Active solution configuration”下选择new。您现在可以将其命名为“Debug - DLL”并将Copy Settings设置为Debug,现在剩下要做的就是定义DLL_CONFIG

要执行此操作,请转到项目属性 - >配置属性 - > C / C ++ - >预处理器,然后在其中键入DLL_CONFIG。您还会看到定义NDEBUGWIN32之类的内容。

haffax said类似,使用项目特定名称。我建议像:

#ifdef THEPROJECT_USE_DLL
    #ifdef THEPROJECT_BUILDING_PROJECT
        #define THEPROJECT_API __declspec(dllexport)
    #else
        #define THEPROJECT_API __declspec(dllimport)
    #endif
#else
    #define THEPROJECT_API
#endif

现在你的DLL的用户只是#define THEPROJECT_USE_DLL,如果他们使用的是DLL版本,就像你的“ - DLL”配置一样。

答案 1 :(得分:3)

只需将MY_API定义为空。像这样:

#ifdef DLL_CONFIG
    #ifdef MY_EXPORTS
    #define MY_API __declspec(dllexport)
    #else
    #define MY_API __declspec(dllimport)
    #endif
#else
    #define MY_API
#endif

在静态链接的情况下,不需要declspec。

如果库的用户想要将其用作dll,或者如果他们想要将其用作静态库,则必须定义DLL_CONFIG。 不会有任何问题。这种配置在许多库中完成。

编辑:当然,您不应该使用名称MY_EXPORTSDLL_CONFIG。为所有宏使用项目特定的前缀,以便没有名称冲突。

答案 2 :(得分:1)

什么都不做。链接静态库不需要特殊的调用约定。您唯一需要做的就是确保链接器与your.lib链接。