所以常见的(至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
。 你也会看到这是NDEBUG
和WIN32
等东西的定义。
像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_EXPORTS
和DLL_CONFIG
。 使用项目特定的前缀为您的所有宏,以便没有名称冲突。
没做什么。 不需要特殊的调用约定来链接静态库。 你唯一需要做的就是确保链接器与你的.lib链接。