2016-05-23 13 views
9

Nagłówek Linux <ncurses.h> definiuje funkcję meta, a biblioteka programowania metaprogramowania C++ meta umieszcza cały swój kod w globalnej przestrzeni nazw meta.Kolizja nazw między przestrzenią nazw biblioteki C++ a funkcją C linux

Jak korzystać z obu programów w tym samym programie C++ (niekoniecznie w tej samej jednostce tłumaczeniowej, ale byłoby to miłe)? Czy istnieje sposób obejścia kolizji nazw?

mogę myśleć o dwóch kruchych obejścia, ale są one łatwe do złamania:

  • Obejście 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> 
    

    kompiluje ale prawdopodobnie nie odwołuje ponieważ ncurses symbole są spodziewane w globalna przestrzeń nazw.

  • Obejście B:

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

    jest bardzo kruchy, ponieważ to będzie działać tylko tak długo, jak biblioteka meta nie zakłada, że ​​każdy z jej symboli znajdują się w globalnej przestrzeni nazw. Oznacza to, że jeśli biblioteka musi ujednoznacznić wewnętrznie symbol i używa do tego ::meta::symbol_name, podejście to zostanie zerwane.

+1

Podejście A nie zadziała, jak sam wiesz. Podejście B może działać - możesz spróbować. Najpierw jednak postarałem się tak bardzo, jak to tylko możliwe, aby przekonać się, czy mogę oddzielić te dwie biblioteki, aby żadna z nich nie korzystała z obu tych funkcji. – SergeyA

+3

Spróbuj napisać opaskę dla jednego, aby nigdy nie zawierał obu nagłówków w tej samej jednostce tłumaczeniowej i mam nadzieję, że linker będzie z nią w porządku. – nwp

+0

@NathanOliver '' ma funkcję o nazwie meta, natomiast '' ma przestrzeń nazw o nazwie 'meta' w globalnym obszarze nazw, więc nazwa funkcji koliduje z nazwą przestrzeni nazw. – gnzlbg

Odpowiedz

7

Proponuję obejście C: Izolowanie swój kod tak, że użycie biblioteki meta i wykorzystanie ncurses są w odrębnych jednostek tłumaczeniowych w projekcie. W ten sposób w dowolnej jednostce tłumaczeniowej nie ma jednego symbolu używanego zarówno jako przestrzeń nazw, jak i funkcja globalna.

+0

Ponieważ meta jest biblioteką tylko nagłówkową, prawdopodobnie łatwiej jest napisać opakowanie o nazwie "", które obejmuje tylko ten nagłówek w pliku cpp. – gnzlbg

+0

@gnzlbg Jeśli się trochę rozejrzysz, jestem pewien, że już istnieją owijki C++ dla biblioteki ncurses, której możesz użyć. :) –

+2

@JoachimPileborg nie jest potrzebny: ncurses zawiera już wiązania C++ (http://stackoverflow.com/questions/544280/c-wrappers-for-ncurses) – Garf365

1

Jestem dość pewny, że ani A, ani B nie będą działać, przynajmniej tak jak dane. Wskazałeś na jednego z nich, ale myślę, że jest to mniej prawdopodobne. Istnieją dwa problemy, które są w zasadzie odbiciami lustrzanymi.

Jeśli kod w ncurses jest zadeklarowana jako extern "C" (typowa dla wielu bibliotek C, które zostały wykonane do pracy z C++), otaczając je z nazw nie będzie faktycznie działa - deklaracja extern "C" zasadzie ignoruje nazw i deklaruje funkcja w globalnej przestrzeni nazw. Przestrzeń nazw niewiele zmieni, a nadal będziesz miał kolizję.

Jeżeli zawartość <ncurses.h> nie jest zadeklarowana extern "C" Pokochasz napotkasz problem ty cytowanym: biblioteka jest zbudowany z funkcji w globalnej przestrzeni nazw, ale kod klient widzi definicje dla kodu w obszarze nazw linux. Ponieważ przestrzeń nazw wpływa na zniekształconą nazwę (w ten sposób zapobiega kolizji), twój kod nie będzie mógł się połączyć. Wszystkie funkcje linux::* będą wyświetlane jako nierozwiązane zewnętrzne.

Aby dokonać tej pracy, trzeba upewnić się, że żaden z kodem biblioteki deklaruje extern "C" i określ nazw wewnątrz nagłówek (i pliki źródłowe Library) i ponownie skompilować bibliotekę z tych deklaracji, więc biblioteka i jej kod klienta zgadzają się na przestrzeń nazw, w której znajduje się ten kod.

Powiązane problemy