跨 DLL/共享库使用命名空间

using a namespace accross DLLs / shared library

提问人:Devolus 提问时间:5/25/2013 最后编辑:CommunityDevolus 更新时间:8/23/2018 访问量:4692

问:

我正在编写一个带有帮助程序函数的共享库/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)'
C++ DLL 命名空间 共享库

评论

0赞 BoBTFish 5/25/2013
呃,这都是windows-y!但我相信答案是你不想尝试导出整个命名空间。导出所需的函数(恰好位于命名空间中)。像这样的东西在修改后变成类似的东西,然后导出该名称。命名空间是源代码中的一个概念,而不是编译的 DLL 中的一个概念。namespace N { int foo(); }int N_foo();
1赞 Samuel 5/25/2013
我认为将实用程序类与静态方法一起使用没有任何问题。由于您正在使用 C++ 而不是 C,因此这是我建议的要走的路。从代码质量的角度来看,在其他命名空间中使用相同的函数无论如何都是不好的,因为这可能会故意隐藏其他命名空间中的函数(un),使代码难以理解并且更容易出错
0赞 Devolus 5/25/2013
@BoBTFish,我的观点是这行不通。当我使用命名空间时,我收到一个链接器错误,说明我尝试调用的函数的未定义符号。
0赞 Devolus 5/25/2013
@Samuel,你说的很有道理,这就是我想出这个解决方法的原因。我仍然不明白为什么这个限制只适用于symblos。此外,它不适用于变量,因为你不能让所有变量都静态,因为这是一个完全不同的概念。好吧,如果我需要变量,无论如何我都会使用类对象,所以这不是一个很大的问题。
2赞 n. m. could be an AI 5/25/2013
“这行不通”---确实如此。看看那个小前缀。它适用于独立功能吗?我是这么认为的。你做错了什么。我无法确切地说出什么,因为你没有展示你在做什么。展示你的代码,然后也许我们可以一起弄清楚。std::

答:

0赞 Steve Townsend 8/23/2018 #1

什么?如果在库和用户代码中包含相同的头文件(q中显示的头文件),则必须根据上下文进行不同的扩展。EXPORT_DECLEXPORT_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