2013-01-21 10 views
5

Ich bin neu in C, so leid für meinen Mangel an Wissen (mein C-Buch hier ist wirklich massiv :)Eine dynamisch verknüpfte gemeinsam genutzte Bibliothek erweitern?

Ich mag eine gemeinsam genutzte Bibliothek (libcustomer.so) mit Closed-Source verlängern, aber den öffentlichen bekannte api.

Ist so etwas möglich?

  1. Umbenennungs libcustomer.so
  2. erstellen eine erweiterte gemeinsame Bibliothek libcustomer.so liboldcustomer.so
  3. Link liboldcustomer.so in meinem erweiterten libcustomer.so über -loldcustomer (so implizit andere die erweiterte man verwenden)
  4. weiterleiten alle nicht extra implementierten Methoden direkt an den alten „liboldcustomer.so“

ich es glaube nicht, dass die Art und Weise funktionieren würde (der Name wird in die .so zusammengestellt, es ist nicht wahr?). Aber was ist die Alternative?

Für # 4: gibt es eine allgemeine Möglichkeit, dies zu tun, oder muss ich eine Methode wie die alte benennen und den Anruf weiterleiten (wie?)?

Da das ursprüngliche libcustomer.so (= liboldcustomer.so) von Zeit zu Zeit ändern kann, sollten alle diese Dinge dynamisch arbeiten. Denken Sie über Extended Validation-Kontrollen

Aus Sicherheitsgründen wird unser System keine LD_PRELOAD hat (sonst würde ich, dass :().

& einige bessere NPE-Handlings.

Vielen Dank im Voraus für Ihre Hilfe

EDIT:

ich meine Erweiterung nur die Umsetzung, wie in der Antwort gezeigt, aber ich habe eine nicht behandelte Fall im Moment:

Wie kann ich die Strukturen aus der erweiterten Bibliothek "Proxy"?

Zum Beispiel habe ich dies:

customer.h:

struct customer; 

customer.c:

struct customer { 
    int children:1; 
    int age; 
    struct house *house_config; 
}; 

nun in meinem kunden extension.c Ich schreibe die ganze Öffentliche Methoden bilden customer.c, aber wie kann ich die Strukturen "durchreichen"?

Vielen Dank für Ihre Zeit & Hilfe!

+0

Die Antwort für Ihre erste zusätzliche Frage ist bereits gegeben. Der zweite ist eng verwandt - C/C++ enthält keine binären Metainformationen wie Java/.NET, so dass Sie nicht erraten können, wie die Definition einer "Kunden" -Struktur aussehen könnte. Selbst wenn Sie sich an die Typen und Namen der Felder in dieser Struktur erinnern, können Probleme mit den Einstellungen des Compilers auftreten - z. B. Feldausrichtung. –

+0

Okay danke. Ich werde jetzt die geschriebene Antwort versuchen :) –

Antwort

5

So haben Sie OldLib mit

void func1(); 
int func2(); 
... etc 

Der Schritt 4 aussehen könnte eine andere Bibliothek mit einigen statischen Initialisierung zu schaffen.

erstellen newlib mit Inhalt:

void your_func1(); 

void (*old_func1_ptr)() = NULL; 
int (*old_func2_ptr)() = NULL; 

void func1() 
{ 
    // in case you don't have static initializers, implement lazy loading 
    if(!old_func1_ptr) 
    { 
     void* lib = dlopen("OldLibFileName.so", RTLD_NOW); 
     old_func1_ptr = dlsym(lib, "func1"); 
    } 

    old_func1_ptr(); 
} 

int func2() 
{ 
    return old_func2_ptr(); 
} 

// gcc extension, static initializer - will be called on .so's load 
// If this is not supported, then you should call this function 
// manually after loading the NewLib.so in your program. 
// If the user of OldLib.so is not _your_ program, 
// then implement lazy-loading in func1, func2 etc. - check function pointers for being NULL 
// and do the dlopen/dlsym calls there. 
__attribute__((constructor)) 
void static_global_init() 
{ 
    // use dlfcn.h 
    void* lib = dlopen("OldLibFileName.so", RTLD_NOW); 

    old_func1_ptr = dlsym(lib, "func1"); 
    ... 
} 

Die static_global_init und alle func_ptr ‚s automatisch generiert werden können, wenn Sie einige Beschreibung der alten API haben. Nachdem die NewLib erstellt wurde, können Sie die OldLib mit Sicherheit ersetzen.

+0

Oh, das ist fantastisch! Ich werde das morgen Abend versuchen und dann Feedback geben. Vielen Dank :) –

+0

Gern geschehen. Und ich muss auch zugeben, dass Sie die Antwort (fast) selbst geschrieben haben :) –

+0

Sehr interessante dynamische Ladetechnik! – loretoparisi

Verwandte Themen