2009-07-07 29 views
5

所以常见的(至少VS 2005点的状态)的方式来确定出口/进口的DLL是:同一个头文件为DLL和静态库

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

class MY_API MyClass { 
    ... 
}; 

这个伟大的工程,如果我只是在我的构建代码作为DLL。但是,我想要使用静态库或DLL的选项。现在一个明显的(但很糟糕的)解决方案是复制所有代码,删除'MY_API'定义的DLL。现在看起来更好的方法是命令行切换来定义或不定义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”)?

回答

12

没有。

将其保留为#define MY_API并且MY_API的所有实例都将简单消失。

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

要克隆配置,请进入配置管理器(如调试/发布列表框的下拉列表),然后在“活动解决方案配置”下选择新建。您现在可以将其命名为“调试 - 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”配置有。

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这样的名称。为所有宏使用项目特定的前缀,以避免名称冲突。

1

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