繁体   English   中英

c ++库命名空间和C linux函数之间的名称冲突

[英]Name collision between c++ library namespace and C linux function

Linux <ncurses.h>头定义了函数meta ,C ++元编程库meta将其所有代码放在全局命名空间meta

我怎样才能在同一个C ++程序中使用它们(不一定是相同的TU,但那会很好)? 有没有办法解决名称冲突?

我可以想到两个脆弱的解决方法,但它们很容易破解:

  • 解决方法A:

      namespace linux { #include <ncurses.h> } // namespace linux using linux::max_align_t; // ncurses assumes it is in the global namespace #include <meta/meta.hpp> 

    编译但可能无法链接,因为在全局命名空间中需要ncurses符号。

  • 解决方法B:

     #include <ncurses.h> namespace cpp { #include <meta/meta.hpp> } // namespace cpp 

    非常脆弱,因为它只有在meta库不假设它的任何符号都在全局命名空间中时才会起作用。 也就是说,如果库需要在内部消除符号歧义并使用::meta::symbol_name ,那么这种方法就会破坏。

我建议解决方法C:隔离您的代码,以便meta库使用和ncurses使用在项目中的单独翻译单元中。 这种方式在任何特定的翻译单元中,没有一个符号被用作命名空间和全局函数。

我有理由相信A和B都不会真正起作用,至少是给定的。 你已经指出了其中一个,但我认为这两个中的可能性较小。 有两个问题基本上是彼此的镜像。

如果ncurses的代码被声明为extern "C" (对于许多使用C ++的C库来说是典型的),用命名空间包围它们实际上不会起作用 - extern "C"声明基本上忽略了名称空间和在全局命名空间中声明一个函数。 命名空间不会改变任何东西,你仍然会发生碰撞。

如果<ncurses.h>的内容未声明为extern "C" ,那么您将遇到引用的问题:库是使用全局命名空间中的函数构建的,但是客户端代码看到了代码的定义。 linux命名空间。 由于命名空间会影响受损的名称(这就是它如何防止冲突),因此您的代码将无法链接。 所有linux::*函数都将显示为未解析的外部。

为了使这项工作,你需要确保没有任何库代码的声明extern "C" ,并指定报头的命名空间(和库源文件),并重新编译这些声明的库,所以库并且其客户端代码同意该代码所在的命名空间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM