在命名空间中包装extern“C”库的问题

时间:2011-08-25 09:34:08

标签: c++ namespaces

我正在使用C ++的C库(libgretl),它的一些函数与我的代码冲突,所以我想把它包装在一个命名空间中,如下所示:

namespace libgretl {
extern "C" {
    #include <gretl/libgretl.h>
}}

然而,这不能编译,我从gcc文件中获得“未定义”错误(在Windows上使用mingw32和gcc 4.5.2)。 第一个错误来自文件c ++ / cstddef的以下代码块:

_GLIBCXX_BEGIN_NAMESPACE(std)
  using ::ptrdiff_t;
  using ::size_t;
_GLIBCXX_END_NAMESPACE

其中宏分别扩展为namespace std {}。之后会有更多错误。

省略extern "C"指令没有用。使用匿名命名空间可以减少错误数量,但仍然无法编译。

因此,我的问题是,是否有某种方法可以包含这样的C库并将其功能放入命名空间,而无需更改gcc或库的源文件?

感谢。

米甲

3 个答案:

答案 0 :(得分:7)

你不能这样做。命名空间不仅仅是源代码装饰,它们被编译器伪装成对象符号。

库中的本机C函数foo()将通过目标文件中的符号_foo提供,但调用bar :: foo()将生成对例如@N3barfoo的引用。因此,将发生链接器错误。

您可以在单独的源文件中创建“代理”函数,包括仅在此源中的原始库头,并将所有代理函数放入命名空间。

答案 1 :(得分:2)

您不必简单地将命名空间包装在外部声明周围并让它出现在该命名空间中......项目(函数,全局)必须从一开始就在该命名空间中构建。由于C不支持名称空间解析,因此情况并非如此。

您需要更改自己的代码才能容纳此库,除非您愿意自己调整库。

为了引用与您自己的命名空间项冲突的非命名空间项,请参阅::item()

答案 2 :(得分:1)

我猜C库被编译为C,这意味着命名空间不包含在编译代码中并且不受支持。因此,编译的C库不能位于命名空间中。通过封装include来改变标题不会改变它。

您仍然可以将自己的代码封装在命名空间中。