2016-05-23 5 views
9

Der Linux-Header <ncurses.h> definiert die Funktion meta, und die C++ - Metaprogrammierungsbibliothek meta setzt ihren gesamten Code in den globalen Namespace meta.Namenskonflikt zwischen C++ - Bibliotheksnamensbereich und C-Linux-Funktion

Wie kann ich beide im selben C++ Programm verwenden (nicht unbedingt die gleiche TU, aber das wäre nett)? Gibt es eine Möglichkeit, den Namen Kollision zu umgehen?

kann ich denke an zwei spröde Abhilfen, aber sie sind leicht zu brechen:

  • Umgehung 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> 
    

    compiliert wird aber wahrscheinlich verbinden fehlschlagen, da die ncurses Symbole erwartet in der globale Namespace.

  • Umgehung B:

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

    ist sehr spröde, da sie nur so lange funktionieren, wie die meta Bibliothek geht nicht davon aus, dass jede seiner Symbole im globalen Namespace ist. Das heißt, wenn die Bibliothek intern ein Symbol disambiguieren muss und dafür ::meta::symbol_name verwendet, wird dieser Ansatz unterbrochen.

+1

Ansatz A wird nicht funktionieren, wie Sie selbst wissen. Ansatz B könnte funktionieren - Sie können es versuchen. Aber ich würde zuerst so viel wie ich kann versuchen, um zu sehen, ob ich diese beiden Bibliotheken trennen kann, so dass keine einzige Transitionseinheit beides verwendet. – SergeyA

+3

Versuchen Sie, einen Wrapper für einen zu schreiben, so dass Sie nie beide Header in dieselbe Übersetzungseinheit einschließen und hoffen, dass der Linker damit einverstanden ist. – nwp

+0

@NathanOliver '' hat eine Funktion namens meta, während '' einen Namespace namens 'meta' im globalen Namespace hat, sodass der Funktionsname mit dem Namespace-Namen kollidiert. – gnzlbg

Antwort

7

würde ich Abhilfe C vorschlagen: Isolieren Sie Ihren Code, so dass die meta Bibliothek Nutzung und die ncurses Verwendung sind in separaten Übersetzungseinheiten in Ihrem Projekt. Auf diese Weise wird in einer bestimmten Übersetzungseinheit nicht ein Symbol sowohl als Namespace als auch als globale Funktion verwendet.

+0

Da Meta nur eine Header-Bibliothek ist, ist es wahrscheinlich einfacher, einen Wrapper um '' zu schreiben, der nur diesen Header in seiner cpp-Datei enthält. – gnzlbg

+0

@gnzlbg Wenn Sie sich ein wenig umsehen, bin ich sicher, dass es bereits C++ - Wrapper für die ncurses-Bibliothek gibt, die Sie verwenden können. :) –

+2

@JoachimPileborg nicht benötigt: Ncurses enthält bereits C++ Bindings (http://StackOverflow.com/Questions/544280/c-Wrappers-for-Ncurses) – Garf365

1

Ich bin mir ziemlich sicher, dass weder A noch B tatsächlich funktionieren werden, zumindest so, wie es ist. Sie haben auf einen von ihnen hingewiesen, aber ich denke, es ist der unwahrscheinlichere der beiden. Es gibt zwei Probleme, die im Grunde Spiegelbilder voneinander sind.

Wenn der Code in ncurses als extern "C" (typisch für viele C-Bibliotheken, die gemacht wurden mit C++ zu arbeiten) erklärt, umgibt sie mit einem Namespace wird nicht wirklich funktionieren - eine extern "C" Erklärung grundsätzlich ignoriert Namespaces und erklärt eine Funktion im globalen Namespace. Der Namespace wird nicht viel ändern, und Sie werden immer noch eine Kollision haben.

Wenn der Gehalt an <ncurses.h> nicht extern "C" erklärt, dann werden Sie in das Problem laufen Sie zitiert: die Bibliothek mit Funktionen im globalen Namensraum gebaut wird, aber der Client-Code wird in dem linux Namespace-Definitionen für Code zu sehen. Da der Namespace den fehlenden Namen betrifft (so verhindert er eine Kollision), kann Ihr Code nicht verlinkt werden. Alle linux::* Funktionen werden als nicht aufgelöste externe angezeigt.

Um diese Arbeit zu machen, müssen Sie keine des Bibliothekscode, um sicherzustellen, dass extern "C" deklariert wird, und den Namespace innerhalb der Header (und die Bibliothek Quelldateien) angeben, und die Bibliothek mit diesen Erklärungen neu zu kompilieren, Die Bibliothek und ihr Client-Code stimmen somit überein, in welchem ​​Namespace sich der Code befindet.

Verwandte Themen