Frage

Duplikat der folgenden Frage: C Funktionskonflikt


Hallo, in meinem aktuellen Projekt muss ich eine Art Interface Lib verwenden. Die Funktionsnamen werden durch diese Schnittstelle angegeben, was diese Funktionen tun, ist die Auswahl der Entwickler. Soweit ich das feststellen kann, soll ein Projekt diese Funktionen verwenden und wenn es darum geht, die LIB und damit die Funktionalität auszuwählen. Ich versuche zu tun, eine vorhandene LIB und meine LIB gleichzeitig zu verwenden, indem ich das andere wickelte und sie in den MEIN -Funktionen nennt:

Andere Lib:

int function1 (int a) {
// do something
}

Mylib:

int function1 (int a) {
//my code here
    otherlib::function1(a);
}

Das Problem ist, dass ich keinen Zugriff auf die andere LIB habe und die andere LIB keine Namespaces hat. Ich habe es schon versucht

namespace old {
    #include "otherlib.h"
}

und rufen Sie dann die alte Funktion von Old :: function1 in meiner Funktion auf. Dies funktioniert so lange, wie es sich nur um eine Header -Datei handelt. Die Lib exportiert das Symbol zurück in den globalen Raum. Auch so etwas wie

namespace new {
    function1 (int a) {
        ::function1(a);
    }
}

hat nicht funktioniert. Last but not least habe ich ifdefs ausprobiert und definiert vorgeschlagene vorgeschlagene hier

Aber ich war nicht erfolgreich.

Irgendwelche Ideen, wie man das löst? Danke im Voraus.

Bearbeiten: Ich habe weder Zugriff auf die alte Bibliothek noch das Projekt, in dem beide Libs verwendet werden sollen.

Edit2: Zumindest ist die alte Bibliothek statisch

War es hilfreich?

Lösung

Namespaces in C mit Bibliotheksnamen Präfixe gelöst wie:

libfoo -> foo_function1
libbar -> bar_function1

Diese Präfixe sind tatsächliche Namespaces. Also, wenn Sie Libbar schreiben

int bar_function1(int a) {
     function1(a);
}

Auf diese Weise können Sie Probleme lösen.

C hat Namespaces-sie haben gerade Präfixe genannt;)

Eine andere Möglichkeit besteht darin, verschiedene schmutzige Tricks mit dynamischem Laden von Bibliotheken wie:

h1=dlopen("libfoo.so")
foo_function1=dlsym(h1,"function1")

h2=dlopen("libbar.so")
bar_function1=dlsym(h2,"function1")

Andere Tipps

Es scheint, als ob die andere LIB C ist und Ihr Code C ++ ist. Sie können auf ein Manglingproblem stoßen (C ++ Compiler fördern die Symbole - fügen Sie zusätzliche Dinge in den Symbolnamen hinzu. Unterscheiden Sie Überladungen und dergleichen).

Wenn die Bibliothek rein ist, können Sie es versuchen:

extern "C" { // disable mangling of symbol names in the block
#include "otherlib.h"
}

namespace new_lib { // new is a reserved word
   int function1( int a ) {
      ::function1(a);
   }
}

Ich habe es nicht versucht. Berücksichtigen Sie auch die Fehlermeldungen, die Sie erhalten.

Eine andere Option wäre (wenn die Bibliothek dynamisch ist), die LIB dynamisch zu laden und die Funktion aufzurufen. In Linux (ich weiß nicht über Windows) können Sie DLOPEN verwenden, um die Bibliothek zu öffnen, DLSym, um das Symbol zu erhalten und es zu nennen:

// off the top of my head, not tried:
int function1( int a )
{
   int (*f)(int); // define the function pointer
   void * handle = dlopen( "library.so" );
   f = dlsym( handle, "function1" );
   f( a ); // calls function1(a) in the dynamic library
}

In diesem Fall erhalten Sie, da Sie nicht mit der Bibliothek verlinken, keinen Symbolkonflikt, aber es gilt nur für dynamische Bibliotheken und ist für den regulären Gebrauch ziemlich umständlich.

AKTUALISIEREN

Wenn Ihre Benutzer "Otherlib" nicht direkt verwenden (sie werden ihre Header nicht enthalten) und sie nur C ++ sein, kann der erste Ansatz möglich sein (auch wenn es schrecklich ist, zu lesen):

// newlib.h
namespace hideout {
   int f( int a );
}
using namespace hideout; // usually I would not put this on the header

// newlib.cpp
extern "C" { // if otherlib is C, else remove this line
#include "otherlib.h"
}
namespace hideout {
   int f( int a ) { return ::f( a*2 ); }
}

// main.cpp
#include "newlib.h"
int main()
{
   std::cout << f( 5 ) << std::endl;
}

Wie funktioniert es? Benutzercode wird nur eine Funktionserklärung 1 (im Beispiel f ()) angezeigt, da sie nicht einbezogen werden otherlib.h. In Ihrer Kompilierungseinheit sehen Sie die beiden Erklärungen, differenzieren jedoch durch die Verwendung des Namespace. Die Verwendung von Anweisung im Header stört Sie nicht, da Sie sich in Ihrem CPP voll qualifizieren. Der Nutzer main.cpp wird nur Ihren Kopfball enthalten, sodass der Compiler nur sehen wird Versteck :: f, und wird es überall aufgrund der Verwendung der Verwendung von Anweisung sehen. Der Linker hat kein Problem, da das C ++ -Symbol verstümmelt wird, um den richtigen Namespace zu identifizieren:

// g++ 4.0 in macosx:
00002dbe T __ZN7hideout9function1Ei // namespace hideout, function1 takes int, returns int
00002db0 T _function1

Wenn der Benutzercode sowohl Ihren Header als auch Ihren Header enthält otherlib.h Dann muss es qualifizieren, welche Funktion es aufrufen möchte.

Wenn Sie wirklich verzweifelt sind, können Sie eine Wrapper -Bibliothek schreiben, die Namespaces oder Präfixe verwendet oder den DLSym -Trick ermöglicht. Diese Wrapper -Bibliothek müsste dynamisch verknüpft sein (um Symbolkonflikte zu vermeiden). Die dynamische Bibliothek könnte dann sicher die alte statische Bibliothek eingebettet haben. Stellen Sie einfach sicher, dass Sie die Symbole nicht aus der statischen Bibliothek exportieren, wenn Sie die dynamische Wrapper -Bibliothek erstellen.

Sie können dies nicht zum Link -Zeitpunkt beheben, sodass Sie es zur Laufzeit über dynamische Bibliotheken beheben müssen. Das Symbol für diese Funktionen ist im Wesentlichen gebacken, sobald die Bibliothek generiert wurde. Wenn zwei Bibliotheken dasselbe Symbol exportieren, können sie nicht beide statisch verknüpft werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top