2016-06-15 11 views
1

Ich möchte auf den ersten Blick sagen, dass ich noch nie mit dynamischen Bibliotheken gearbeitet habe. Es ist also möglich, dass ich nicht einmal verstehe, wie sie richtig funktionieren.Lokale dynamische Bibliothek

Ich möchte einen voll geladenen Code ausführen und nach einigen Trigger (wahrscheinlich Benutzerinteraktion) möchte ich eine bestimmte Bibliothek laden und eine Funktion innerhalb dieser Bibliothek ausführen. Schließen Sie es vorzugsweise danach. Im Wesentlichen erlauben Sie mir, es zu ändern und während der Laufzeit neu zu laden.

Dies ist die einfache dynamische Bibliothek (dynlib.so befindet sich im selben Verzeichnis wie die Haupt-Code genannt):

int getInt(int arg_0) 
{ 
    return (arg_0 + 7); 
} 

Und das ist das Hauptprogramm:

#include <iostream> 
#include <dlfcn.h> 

int main() { 
    void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW); 
    if (!lib_handle) { 
    fprintf(stderr, "%s\n", dlerror()); 
    exit(EXIT_FAILURE); 
    } 

    typedef int (*func_ptr)(int); 
    func_ptr func = (func_ptr)dlsym(lib_handle, "getInt"); 
    std::cout << func(13); 

    dlclose(lib_handle); 
} 

I Ich kompiliere es mit: g ++ -std = C++ 11 -ldl loadlibtest.cpp -o Haupt.

Der Fehler, den ich fange, ist ./libshared.so: Datei zu kurz In meinem if (!lib_handle) {.

+0

Offensichtlich hat Ihre 'dynlib.so' Probleme. Wie wurde es erstellt? – SergeyA

+0

hast du versucht, nm-D dynlib.so? – Jimmy

+0

@SergeyA Nicht sicher, was Sie damit meinen, aber ich denke "manuell". – areuz

Antwort

3

Es funktioniert gut für mich. Ich kompiliert haben dynlib.so mit

$ gcc dynlib.c -fPIC -shared -o dynlib.so 

(Natürlich müssen Sie entweder kompilieren, wie C oder C++ mit extern "C" Namen Mangeln zu vermeiden).

und ich musste -ldl nach der Quelldatei im g++ Aufruf platzieren.

gcc: 4.8.5; ++ g: 5.3.0


dlsym kann von Leere zu und Gießen scheitern * Zeiger auf Funktion ist technisch UB. Sie sollten es auf Basis der usage snippet from the manpage (für Ihre Funktion modifiziert):

 dlerror(); /* Clear any existing error */ 

     /* Writing: func = (int (*)(int)) dlsym(handle, "getInt"); 
      would seem more natural, but the C99 standard leaves 
      casting from "void *" to a function pointer undefined. 
      The assignment used below is the POSIX.1-2003 (Technical 
      Corrigendum 1) workaround; see the Rationale for the 
      POSIX specification of dlsym(). */ 

     *(void **) (&func) = dlsym(handle, "getInt"); 

     if ((error = dlerror()) != NULL) { 
      fprintf(stderr, "%s\n", error); 
      exit(EXIT_FAILURE); 
     } 
+0

Ich habe die externe Verknüpfung hinzugefügt und der Fehler ist jetzt *./Dynlib.so: ungültige ELF-Header *. ^^ Damit habe ich es auch mit * g ++ -std = C++ 11 -fPIC loadlibtest kompiliert.cpp -ldl -o main * Sowohl g ++ als auch gcc sind 4.8.4. – areuz

+1

@areuz Frage ist, wie kompilieren Sie dynlib.so? 'g ++ -fPIC -shared dynlib.cc -o dynlib.so' wo dynlib.cc die' getInt' Definition ist, die in 'extern 'C eingepackt ist, funktioniert für mich gut. – PSkocik

+0

In Ihrer letzten Bearbeitung haben Sie * func * und * error * nicht definiert. Aber ich erwarte * Fehler * ein Char zu sein. – areuz

1

Nach einigen großen Antworten, die ich entdeckte, was ich falsch mache.

1) Ich habe nicht extern "C" für meine Bibliothek Funktionen, so dlsym konnte die Funktion nicht finden.

2) Ich wusste nicht, dass dynamische Bibliotheken kompiliert werden mussten < < ziemlich dumm von mir.

Ich möchte immer noch wissen, ob es eine Möglichkeit gibt, nicht kompilierten Code als eine Bibliothek zu verwenden, aber mein erstes Problem wurde gelöst, danke an alle.

+1

Es gibt eine Möglichkeit, nicht kompilierten Code als gemeinsam genutzte Bibliothek zu verwenden. Der Weg wird Kompilation genannt. ;-) C und C++ sind keine Sprachen, die für die Laufzeitinterpretation ausgelegt sind. Wenn Sie dynamisch geladene Plugins müssen als Quelle zur Verfügung gestellt werden, dann ist es Ihr Programm muss es zuerst für sich selbst kompilieren. – PSkocik

+0

@PSkocik Danke :) Ich werde das untersuchen, es kann nicht so schwer sein. – areuz