因此,定义DLL的导出/导入的常见(至少VS 2005状态)方式是:
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
class MY_API MyClass {
...
};
Run Code Online (Sandbox Code Playgroud)
如果我只是将我的代码构建为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 {
...
};
Run Code Online (Sandbox Code Playgroud)
现在假设可以这样做,当库的用户包含头文件时会出现问题(即他们是否必须定义'DLL_CONFIG')?
GMa*_*ckG 13
没有.
保留它#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所说,使用项目特定的名称.我建议像这样:
#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
Run Code Online (Sandbox Code Playgroud)
现在你的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
Run Code Online (Sandbox Code Playgroud)
在静态链接的情况下,不需要 declspec。
库的用户必须定义DLL_CONFIG是否要将其用作 dll,或者如果要将其用作静态库则不定义。照原样不会有任何问题。许多库中都进行了这种配置。
编辑:当然,您不应该使用名称MY_EXPORTS等DLL_CONFIG。对所有宏使用项目特定的前缀,这样就不会出现名称冲突。