在命名空间中包装外部"C"库时出现问题

problem wrapping extern "C" library in a namespace

本文关键字:问题 包装 外部 命名空间      更新时间:2023-10-16

我正在使用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或库的源文件?

谢谢。

米甲

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

库中的原生C函数foo()将通过对象文件中的symbol _foo可用,但调用bar::foo()将生成对例如@N3barfoo的引用。因此,将发生链接器错误。

你可以在单独的源文件中创建"proxy"函数,只在该源文件中包含原始库头文件,并将所有代理函数放在命名空间中。

您不能简单地将名称空间包装在外部声明周围,并让它出现在该名称空间中…项目(function, global)必须从一开始就在该名称空间内构建。由于C语言不支持命名空间解析,所以不可能出现这种情况。

你需要修改你自己的代码来适应这个库,除非你愿意改变库本身。

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

我猜C库被编译为C,这意味着在编译的代码中不包括也不支持名称空间。因此,编译后的C库不能在命名空间中。通过封装include来改变头文件不会改变这一点。

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