Fremden code in ein namespace einkapseln um konflikte zu vermeiden.. wie?



  • Hallo Leute,

    ich muss zur meiner Diplomarbeit eine Fremde Implementierung eines Algorithmus nutzen und diesr ist müllig programmiert. Wenn auch effizient.
    Das Problem ist, dass dort ALLE Klassen im globalen Namensraum (namespace) deklariert sind.
    Wenn ich also etwas davon einbinde kommt es zu Konflikten mit meinen Namesräumen.
    Ich würde aber gerne diesen fremden Code mit

    namespace assLib{
    #include <Matrix.h>
    }
    
    assLib::Matrix(...)
    

    einkapseln.
    Das Problem dabei ist, dass ich nun nicht weiss wie ich dem Linker mitteilen kann die Methoden in der fremden Bibliothke zu finden.

    Hier eine Beispielstruktur aus dem fremden Code:
    Headerdatei Matrix.h:

    #include "somefile.h"
    class Matrix
    {
    public:
    ...
    }
    

    Source Matrix.cpp:

    #include "Matrix.h"
    ...
    

    Gibt es vielleicht eine andere Möglichkeit mit solchem Problem umzugehen?
    Leider ist es in meinem bereich sehr üblich, dass open source projekte an unis nicht von informatikern programiert wurden und solche "feinheiten" nicht beachtet werden.

    Würde mich total freuen, wenn mir da jemand einen tipp geben könnte.

    vielen dank und viele grüße

    PS: ich nutze CMake um den Linker zu steuern.



  • Am besten wäre da natürlich Zugriff auf die eine oder andere Klasse, so dass du dort einen normalen Namensraum hinzufügn kannst.

    Ansonsten fällt mir da eigentlich so auf die schnelle nur Makro Gefrickel ein, mit dem du dann Sachen umbenennst, aber das wird sehr hässlich, aber da hättest du dann ja sowieso Zugriff auf den Source Code und könntest auch gerade von Hand machen.

    Ich würde eher probieren die Konflikte zu vermeiden, indem du nur den einen Header includest.



  • Halo mojo777,

    ... dass ich nun nicht weiss wie ich dem Linker mitteilen kann die Methoden in der fremden Bibliothke zu finden.

    Wie wird denn gelinkt ? statische lib, dynamische lib ???

    Das beste wäre warswcheinlich,
    wenn du den fehlenden namespace einfügst und ihn,
    z.B. per #define aktivierst und die lib neu compilierst und linkst.

    Bei einer dynamischen lib kannst du die symbole mit loadlibrary,
    ... selbst, zur Laufzeit laden und hast damit keine probleme zur compilezeit.

    Gruß Frank



  • Wenn die Bibliothek schon gebaut ist, dann liegen die Symbole darin im globalen namespace. Und wenn man den Header dann in eine "using namespace XY"-Klammer verpackt, wird der Linker garnichts mehr finden.
    Was du machen könntest wäre eine strikte Trennung der Bibliothek von deinem restlichen Code, indem du selbst einen Header definiert, der in einem angemessenen Namespace Funktionen bereitstellt, die so ähnlich (oder genauso) heißen wie die Bibliotheksfunktionen. In der .cpp zu diesem Header rufen die Funktionen dann einfach die Bibliotheksfunktionen auf.

    //Bibliotheksheader
    
    void SomeLibFunctionInGlobalScope();
    
    //mylibwrapper.h
    namespace wrapthelib
    {
      void SomeLibFunction();
    }
    
    //mylibwrapper.cpp
    #nclude libheader.h //die einzige Stelle, wo der Header eingebunden wird!
    
    namespace wrapthelib
    {
      void SomeLibFunction()
      {
        SomeLibFunctionInGlobalScope();
      }
    }
    


  • @pumuckl:
    (Das ist ne Ergänzung zu deinem Beitrag, ich gehe davon aus dass du das eh alles weisst)

    Das geht gut, so lange die "böse" Library keine Namen exportiert (external linkage) die woanders auch noch vorkommen (CRT/SCL bzw. andere "böse" Library).
    Ansonsten klescht es beim Linken trotzdem.

    Da hilft dann nur noch alle Source-Files abändern und die böse Library neu bauen.

    Ohja: unter Windows geht die von dir beschriebene Methode schon, und zwar wenn man ne Wrapper-DLL verwendet. Ist aber genau genommen eine Verletzung der ODR, auch wenn die Implementierung in dem Fall garantiert dass es so funktioniert wie man möchte.
    (Wie das unter Linux mit SOs aussieht weiss ich nicht)


Anmelden zum Antworten