提问人:Devolus 提问时间:5/25/2013 最后编辑:CommunityDevolus 更新时间:8/23/2018 访问量:4692
跨 DLL/共享库使用命名空间
using a namespace accross DLLs / shared library
问:
我正在编写一个带有帮助程序函数的共享库/DLL。因此,我声明命名空间将来不会发生名称冲突。对于类,这很好用,但我有一些全局函数,我也想放在命名空间中,但这不起作用。尝试对命名空间进行寻址时出现链接器错误。看起来命名空间似乎无法从 DLL 内部导出。
我用谷歌搜索并在这里找到了这个线程 我应该把我的 DECLSPEC 放在命名空间的什么地方? 我不明白答案。命名空间的重点是分离名称并使其具有统一的可识别性,所以我想知道为什么这是一个公认的答案,说不需要导出命名空间。但是,也许我在这里遗漏了一些东西。我可以看到命名空间本身无法导出,但里面的函数仍然应该属于命名空间,这似乎是不可能的。但是,我在命名空间中获取的类按预期工作,所以我有点困惑为什么这不应该也适用于其他符号。
现在,我通过创建一个虚拟类包装器来结束,并将我的函数声明为静态的。它不是 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;
}
主 .cpp:
int x = mytest::mytestfkt(1);
x = mytest::decltest(1);
结果:
undefined reference to `mytest::mytestfkt(int)'
undefined reference to `mytest::decltest(int)'
答:
什么?如果在库和用户代码中包含相同的头文件(q中显示的头文件),则必须根据上下文进行不同的扩展。EXPORT_DECL
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
评论
namespace N { int foo(); }
int N_foo();
std::