Anzeige:
Ergebnis 1 bis 11 von 11

Thema: Shared Lib Problem

  1. #1
    Registrierter Benutzer
    Registriert seit
    05.06.2006
    Beiträge
    103

    Shared Lib Problem

    Hallo.

    Ich versuche mich grade an dynamic linking mit C unter Linux. Ich mache zum Test folgendes:

    Eine Datei dltest.c mit dem Inhalt

    Code:
    #include <stdio.h>
    
    void hello () {
      printf ("Hello World.\n");
    }
    Die ich compiliere mit den Kommandos
    Code:
    $ gcc -c -fPIC -DPIC dltest.c
    $ gcc -shared -Wall dltest.o -lc -Wl,-soname -o dltest.so
    Eine Datei test.c mit dem Inhalt

    Code:
    #include <stdio.h>
    #include <dlfcn.h>
    
    int main (int argc, char* argv[]) {
      if (argc != 3) {
        printf("Fehler");
        return -1;
      }
      void* handle = dlopen(argv[1], RTLD_LAZY);
      if (!handle) printf("Could not load %s\nError:%s\n", argv[1], dlerror());
    
      typedef void (*hello_t)();
      dlerror();
      hello_t hello = (hello_t) dlsym (handle, argv[2]);
      const char* dlsym_error = dlerror();
      if (dlsym_error) {
        printf("Fehler: %s\n", dlsym_error);
        dlclose(handle);
        return -1;
      }
      hello();
    
      dlclose(handle);
    
      return 0;
    }
    die ich compiliere mit
    Code:
    $ gcc -o test test.c -ldl
    Alles quick and dirty, sollte nur mal ein Test sein, ob das Ganze funktioniert.

    So. Nun hatte ich mir erhofft, dass der Aufruf

    Code:
    ./test dltest.so hello
    Irgendwie die entsprechende Funktion ausführt. Das ist leider nicht so, ich bekomme die Fehlermeldung
    Code:
    Fehler: ./test: undefined symbol: hello
    Speicherzugriffsfehler
    Bleibt die Frage: Was mache ich falsch. Sicherlich ein Anfängerfehler, aber keine Ahnung.

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Also bei mir funktioniert das - vorausgesetzt natürlich die Bibliothek dltest.so ist im Suchpfad für Bibliotheken (entweder in /etc/ld.so.conf(.d) oder in der Umgebungsvariable LD_LIBRARY_PATH)

    Code:
    peschmae@sid:/tmp/dl$ ./test dltest.so hello
    Could not load dltest.so
    Error:dltest.so: cannot open shared object file: No such file or directory
    Fehler: ./test: undefined symbol: hello
    Speicherzugriffsfehler
    peschmae@sid:/tmp/dl$ LD_LIBRARY_PATH=. ./test dltest.so hello
    Hello World.
    peschmae@sid:/tmp/dl$
    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Registrierter Benutzer
    Registriert seit
    05.06.2006
    Beiträge
    103
    Ah. Ich Idiot. Wenn ich ./dltest.so angebe, gehts auch... Aber seltsam... Geht es garantiert, wenn man den absoluten Pfad angibt, auch ohne dass die LD-Paths gesetzt sind, oder geht das nur zufaellig bei mir?

  4. #4
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Ja, laut der manpage soll das auch gehen mit absoluten (oder auch mit relativen) Pfadnamen.

    Kommt natürlich immer drauf an was genau du willst, aber es ist sicher nicht üblich hier absolute Pfadnamen zu verwenden und damit dem System quasi vorzuschreiben wo genau die Bibliothek zu liegen hat. Verschiedene Systeme haben da verschiedene Konventionen und mit absoluten Pfaden machst du den Paketierern nur das Leben unnötig schwer.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  5. #5
    Registrierter Benutzer
    Registriert seit
    05.06.2006
    Beiträge
    103
    Nunja. Ich will das fuer eine Art Plugin-System (ansonsten wuerd ich das Prog gleich gegen die Library linken, und mir nicht die Arbeit mit dlsym machen).

    Hab mir eigentlich gedacht, dass alle .so-Dateien in einem Verzeichnis liegen, oder in ner Konfigurationsdatei stehen oder so. Aber das wird dann schon gehen, bzw. wenn das nicht geht, kann ich das Prog dann immernoch anpassen.

    Hm. Noch zwei dumme Fragen.

    Zum Einen wollt ich fragen, ob man irgendwie feststellen kann, welche argumente eine Funktion, die ich mit dlsym hole, erwartet, bzw. wenigstens, wie viele Bytes oder so (ich weiss ja nicht, wie das ABI genau aussieht, ob da genauere Infos gespeichert werden).

    Bzw. ob es nen fehler gibt, wenn die Signatur meines Funktionspointers falsch ist.

    Zum Anderen... Kann man das auch aus anderen Input-Streams oder so machen, also muss es unbedingt eine .so-file sein, die ich lade, oder kann ich meinetwegen auch ueber ein char* oder void* den binaercode der .so-file irgendeiner funktion uebergeben (im grunde sollte das ja gehen, sobald die architektur stimmt, nachdem die dateien ja so oder so geladen werden muessen).

  6. #6
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von schoppenhauer Beitrag anzeigen
    Zum Einen wollt ich fragen, ob man irgendwie feststellen kann, welche argumente eine Funktion, die ich mit dlsym hole, erwartet, bzw. wenigstens, wie viele Bytes oder so (ich weiss ja nicht, wie das ABI genau aussieht, ob da genauere Infos gespeichert werden).

    Bzw. ob es nen fehler gibt, wenn die Signatur meines Funktionspointers falsch ist.
    Das kannst du eigentlich problemlos selber testen
    (Btw. ja, es gibt einen Fehler)

    Zum Anderen... Kann man das auch aus anderen Input-Streams oder so machen, also muss es unbedingt eine .so-file sein, die ich lade, oder kann ich meinetwegen auch ueber ein char* oder void* den binaercode der .so-file irgendeiner funktion uebergeben (im grunde sollte das ja gehen, sobald die architektur stimmt, nachdem die dateien ja so oder so geladen werden muessen).
    Ich glaube nicht dass das möglich ist. Nicht wegen prinzipellen Problemen sondern weils halt keine dl...-Funktion gibt die das macht.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  7. #7
    Registrierter Benutzer
    Registriert seit
    05.06.2006
    Beiträge
    103
    Zitat Zitat von peschmae Beitrag anzeigen
    Das kannst du eigentlich problemlos selber testen
    (Btw. ja, es gibt einen Fehler)
    Naja, die Frage ist ja eher, wie findet man die Signatur raus, bzw. gibt es da ne Moeglichkeit? Also wenns nen Fehler gibt, muss die Library ja auch irgendwo speichern, welche Argumente sie bekommt. Dann sollte man das doch auch rausfinden koennen.

    Zitat Zitat von peschmae Beitrag anzeigen
    Ich glaube nicht dass das möglich ist. Nicht wegen prinzipellen Problemen sondern weils halt keine dl...-Funktion gibt die das macht.
    Naja, das kann man dann ja noch schreiben, vermutlich reicht es sogar, ein unix-domain-socket oder eine fifo zu erstellen, und das dann dlopen zu uebergeben, aber das kann ich dann ja ggf. probieren.
    Oder eben die Dateien in einen Tempordner zu speichern. Aber wahrscheinlich brauch ich das sowieso nicht.

    Danke jedenfalls soweit. Hat mir schon sehr geholfen.

  8. #8
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von schoppenhauer Beitrag anzeigen
    Naja, die Frage ist ja eher, wie findet man die Signatur raus, bzw. gibt es da ne Moeglichkeit? Also wenns nen Fehler gibt, muss die Library ja auch irgendwo speichern, welche Argumente sie bekommt. Dann sollte man das doch auch rausfinden koennen.
    Wozu genau? Wenn du eine Funktion ausführen willst musst du ja eh wissen was für eine Bedeutung die jeweiligen Argumente haben bzw. was du da reintun musst...

    Wüsste jetzt gerade von keiner libc-Funktion die das macht. Das Programm objdum kann diesbezüglich z.B. was auslesen, aber afaik ausschliesslich wenn die Debug-Option beim Kompilieren aktiviert ist.

    MfG Peschmä
    Geändert von peschmae (20-06-2007 um 17:47 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  9. #9
    Registrierter Benutzer
    Registriert seit
    05.06.2006
    Beiträge
    103
    Zitat Zitat von peschmae Beitrag anzeigen
    Wozu genau? Wenn du eine Funktion ausführen willst musst du ja eh wissen was für eine Bedeutung die jeweiligen Argumente haben bzw. was du da reintun musst...
    Nunja. Nicht unbedingt. Also ich persönlich hab dadurch ggf. nur ne Kontrollierende Anwendung, aber... Man nehme mal z.B. Script-Engines her, die Funktionen aus Shared Libs ansteuern können. Die müssen ja auch irgendwie wissen, welche Signaturen deren Funktionen haben. Und Compiler und Linker letztendlich auch. Und naja... Keine Ahnung. Also ich persönlich hab dafür wie gesagt kaum eine Anwendung, aber, Java Reflections (das ist ja das direkte Java-Adäquat dazu) bieten sowas z.B. auch - natürlich ist Java wesentlich stärker abstrahiert, das heißt, man kann sowas auch wirklich leichter, soweit ich weiß ist bei C im Wesentlichen festgelegt, wie viele Bytes übergeben werden, und der Rest wird vom Compiler erledigt (da müsst ich mal probieren, ob es nen Unterschied macht, ob man void a(int) oder void a(char, char, char, char) macht - also ob er den Fehler merkt - wenn nicht orientiert er sich wohl nur an der Byte-Zahl). Jedenfalls... Irgendwas muss anscheinend eingespeichert sein, und sobald irgendwas eingespeichert ist, ist es ja auch interessant, wie man es auslesen kann.

    Aber wie gesagt, das ist nur Interesse, brauchen tu ich es sicher nicht, bzw. wenn ich sowas bräuchte, dann müsste ich halt mein Plugin-System entsprechend abstrahieren.

  10. #10
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Du könntest eines der Systeme benutzen, die in C mittels Zusatzinformationen etwas ähnliches wie Reflection bewerkstelligen, also zB das GLib Objektmodell GObject.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  11. #11
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von schoppenhauer Beitrag anzeigen
    Jedenfalls... Irgendwas muss anscheinend eingespeichert sein, und sobald irgendwas eingespeichert ist, ist es ja auch interessant, wie man es auslesen kann.
    Achso, *irgendwo* ist das natürlich schon gespeichert. Da müsste man sich an der Stelle wohl die Dokus zum ELF-Format reinziehen.

    Meine Linksammlung erwähnt auch noch das hier. Habs aber nie durchgelesen: http://www.iecc.com/linker/

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •