我正在编写一个带辅助函数的共享库/ DLL。所以我声明名称空间不会在将来发生名称冲突。对于类,这工作正常,但我有一些全局函数,我也想放在命名空间中,这不起作用。当我尝试寻址命名空间时,我收到链接器错误。看起来好像无法从DLL内部导出名称空间。
我用Google搜索并在此处Where should I put my DECLSPEC for a namespace?找到了这个帖子,我并不完全理解答案。命名空间的要点是分隔名称并使它们无法识别,所以我想知道为什么它是一个公认的答案,说不需要导出namspace。但是,也许我在这里遗漏了一些东西。我可以看到它自己的命名空间无法导出,但里面的函数仍然属于命名空间,这似乎是不可能的。但是,我在命名空间中使用的类按预期工作,所以我有点困惑为什么它不适用于其他符号。
我现在通过创建一个虚拟类包装器并将我的函数声明为static来结束。它不像命名空间那样100%,但它与我的目的相似。
在DLL中:
class EXPORT_DECL Base64
{
public:
static std::string encode(unsigned char const *bytes_to_encode, unsigned int in_len);
static std::string decode(std::string const &oBase64Encoded);
};
在主要内容中我可以像在命名空间中那样解决它们。
Base64::encode(...);
我想知道,如果我在这里遗漏了一些内容,可以使用命名空间而不是使用此解决方法。并且共享库也有这个限制,或者这只是来自DLL的东西吗?
更新
共享库foo.h:
namespace mytest
{
int mytestfkt(int a);
EXPORT_DECL int decltest(int a);
}
共享库foo.cpp。
int mytestfkt(int a)
{
return 0;
}
int decltest(int a)
{
return 0;
}
或者这个:
namespace mytest
{
int mytestfkt(int a)
{
return 0;
}
EXPORT_DECL int decltest(int a)
{
return 0;
}
}
或者这个:
int mytest::mytestfkt(int a)
{
return 0;
}
EXPORT_DECL int mytest::decltest(int a)
{
return 0;
}
main.cpp中:
int x = mytest::mytestfkt(1);
x = mytest::decltest(1);
结果:
undefined reference to `mytest::mytestfkt(int)'
undefined reference to `mytest::decltest(int)'
答案 0 :(得分:0)
什么是EXPORT_DECL
?如果在库和用户代码中包含相同的头文件(q中显示的头文件),则EXPORT_DECL
必须根据上下文进行不同的扩展。
在库中,它必须映射到__declspec(dllexport)
,在用户代码中,它必须扩展到__declspec(dllimport)
。否则,您要告诉编译器从库和用户代码中导出相同的符号。由于用户中没有EXPORT_DECL
标记符号的定义(正确的是,因为您要从库中导入符号),因此会出现链接时错误。
通常,这是通过为EXPORT_DECL
提供条件定义来完成的
#ifdef EXPORTING
#define EXPORT_DECL __declspec(dllexport)
#else
#define EXPORT_DECL __declspec(dllimport)
#endif
然后使用-DEXPORTING=1
编译您的库,并使用-DEXPORTING=0
编译用户代码