因此,定义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')?
答案 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
。您还会看到定义NDEBUG
和WIN32
之类的内容。
与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_EXPORTS
和DLL_CONFIG
。为所有宏使用项目特定的前缀,以便没有名称冲突。
答案 2 :(得分:1)
什么都不做。链接静态库不需要特殊的调用约定。您唯一需要做的就是确保链接器与your.lib链接。