#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
我如何/在哪里定义COMPILING_DLL
?
见到这里:what does __declspec(dllimport) really mean?
听起来我不能使用加载时动态链接,如果我不能使用相同的标题?
定义COMPILING_DLL=1
的最佳位置是编译器的命令行。如果您使用Visual Studio IDE,则它位于项目属性... C / C ++ ...预处理器...预处理器定义。
__declspec(dllimport)
是Microsoft特有的C ++扩展。微软拥有出色的在线文档。
另一种选择:
使用项目的本地默认定义宏。
您可以在以下位置查看项目本地的默认定义宏:
属性 - > C / C ++ - >预处理器 - >预处理器定义。
例:
假设您的项目名称是:MyDLL
默认宏本地项目:MYDLL_EXPORTS
#ifdef MYDLL_EXPORTS
/*Enabled as "export" while compiling the dll project*/
#define DLLEXPORT __declspec(dllexport)
#else
/*Enabled as "import" in the Client side for using already created dll file*/
#define DLLEXPORT __declspec(dllimport)
#endif
在DLL项目中,为#define
添加COMPILING_DLL
(在头文件或项目属性中)。因为这不会为任何其他项目设置(特别是如果你命名它比COMPILING_DLL
更好),那么#if
指令将正常工作。
您(在理想情况下实际上是Visual Studio)在构建DLL时将COMPILING_DLL
定义为编译器的参数。所以,它将默认为__declspec(dllexport)
。另一方面,当您使用DLL的头文件时,您没有定义它,因此DLLEXPORT
将默认评估为__declspec(dllimport)
。
您无法在头文件中以这种方式定义函数体。这是prohibited by __declspec(dllimport)。此说明符只能在函数声明中指定,而不能在定义中指定。
您必须将函数体移动到源文件。
在头文件中:
extern DLLEXPORT void test2();
在.cpp文件中:
void test2()
{
// ...
}
正如大家所说,不要忘记将COMPILING_DLL添加到项目预处理器定义中。
实际上,真正的问题是预处理器指令。您应该使用#ifdef
而不是#if
来测试变量是否真正定义(并且我们不关心定义的值或是否有任何变量)。
注意:我知道这个帖子已经有1年了,但是对于将来遇到这个问题的人来说它仍然有用。
如果您使用CMake生成构建配置,您应该能够以您想要使用<projectname>_EXPORTS
的方式使用宏COMPILING_DLL
,其中projectname
是使用CMake命令project(projectname)
定义的:
检测到共享库编译时,会定义预处理器宏
<target_name>_EXPORTS
。
我测试了它在Windows上使用Ninja生成器和Visual Studio 2015 Express的编译器MSVC。