DLL和静态库的相同头文件

所以常见的(至lessVS 2005状态)为DLL定义导出/导入的方法是:

#ifdef MY_EXPORTS #define MY_API __declspec(dllexport) #else #define MY_API __declspec(dllimport) #endif class MY_API MyClass { ... }; 

这很好,如果我只是build立我的代码作为DLL。 但是,我想要使用静态库或DLL的选项。 现在一个明显的(但可怕的)解决scheme是复制所有代码,删除'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')时会出现问题吗?

没有。

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

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

要克隆配置,请进入配置管理器(如“调试/发布”列表框的下拉列表),然后在“活动解决方案配置”下选择新建。 您现在可以将其命名为“Debug – DLL”并将“ Copy Settings为“ Debug ,现在要做的就是定义DLL_CONFIG

要做到这一点,去项目属性 – >配置属性 – > C / C ++ – >预处理器,并在那里键入DLL_CONFIG 。 你也会看到这是NDEBUGWIN32等东西的定义。

像haffax说的那样 ,使用项目特定的名字。 我会建议像这样的东西:

 #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”配置。

只要将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_CONFIG如果他们想要使用它作为一个DLL或不定义它,如果他们想使用它作为一个静态库。 不会有任何问题。 这种配置在许多库中完成。

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

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