main Funktion in shared object (.so)???



  • Hallo,
    ich beschäftige mich gerade mit dem erstellen von shared object dateien unter linux und habe nun schon in dem einen oder anderen beispiel eine main funktion darin gesehen.
    Da ich eigentlich nur ein paar Funktionen auslagern will ist meine Frage ob ich überhaupt eine main funktion benötige und für was diese in .so Dateien überhaupt gut sind???
    Gruß Wolle.



  • Das ist kein Alleinstellungsmerkmal von shared libraries, d.h. es ist uninteressant, ob shared libraries oder statische libraries.

    Eine main-Funktion macht in einer library erst einmal wenig Sinn. Die einzelnen Library-Module sollen ja dazu benutzt werden, um von verschiedenen Programmen (sprich: ausgehend von der main-Funktion) irgendwann einmal aufgerufen zu werden.

    Theoretisch kann man aber durchaus die main-Funktion in eine Library packen. Meistens passiert das dann in einem Makefile. Dadurch sehen alle Compile-Abläufe identisch aus. Anschließend holt man das Modul mit der gewünschten main-Funktion wieder im Makefile explizit heraus und bindet dann sein Programm zusammen.
    Das hat auch den Vorteil, man hat alle *.o Object-Files auschließlich in Libraries und keine Object-Files mehr in irgendeiner Subdirectory.

    Es kann aber Probleme geben, wenn es eine zweite Library gibt, die beim Binden des Programms referenziert wird und in dieser Library ein Modul enthalten ist, dass (a) auch eine main-Funktion enthält, (b) eine weitere Funktion o.ä. enthält und (c) diese Funktion dann über das eigene main aufgerufen wird.

    Deshalb also eher der Rat: Keine main-Funktion in eine Library! Macht nicht wirklich einen Sinn 😉



  • Danke schön, hast mir echt weitergeholfen.
    Gruß Wolle.



  • Die Verwendung der main Funktion in einer Bibliothek macht in den meisten Fällen keinen Sinn. Aber manchmal kann es ganz nützlich sein, wenn eine Biblothek beispielsweise irgendetwas ausführt, bevor die das Programm startet, z.b. Parameter parsen, oder so.

    Bsp:

    $ mkdir test
    $ cd test
    $ mkdir lib
    $ cd lib
    
    /* mylib.h */
    
    #ifndef MYLIB_H
    #define MYLIB_H
    
    void foo1();
    void foo2();
    void foo3();
    
    #endif
    
    /* mylib.c */
    
    #include <mylib.h>
    #include <stdio.h>
    
    void foo1()
    {
            printf("das ist foo1()\n");
    }
    
    void foo2()
    {
            printf("das ist foo2()\n");
    }
    
    void foo3()
    {
            printf("das ist foo3()\n");
    }
    
    int main(int argc, char* argv[])
    {
            printf("vor dem Start des Programms \"%s\" macht die Bibliothek mylib irgendwas wichtiges\n\n", argv[0]);
    
            /* do something */
    
            return mylib_main(argc, argv);
    
            return 0;
    
    }
    

    Kompilieren...

    $ gcc -shared mylib.c -I. -olibmylib.so
    $ cd ..
    

    und testen

    /* test.c */
    
    #include <mylib.h>
    
    int mylib_main(int argc, char* argv[])
    {
            printf("Hello World mit mylib\n");
    
            foo1();
    
            foo2();
    
            foo3();
    
            return 0;
    }
    

    kompilieren und ausführen

    $ gcc -I./lib/ -L./lib/ test.c -otest -lmylib
    $ LD_LIBRARY_PATH=./lib ./test           
    vor dem Start des Programms "./test" macht die Bibliothek mylib irgendwas wichtiges
    
    Hello World mit mylib
    das ist foo1()
    das ist foo2()
    das ist foo3()
    $
    

    ich habe aber ehrlich gesagt, noch keine Bibliothek gesehen, die so etwas benutzt.



  • Ah danke schön, erklärt einiges.

    Bei mir ist mittlerweile noch eine andere Frage aufgekommen.
    Unter windows ist es mit einer dll ja möglich diese in das selbe Verzeichnis wie die Ausführbare Datei zu legen.
    Ist so etwas auch mit einer so Datei möglich???

    Gruß Wolle.



  • Wolle. schrieb:

    Unter windows ist es mit einer dll ja möglich diese in das selbe Verzeichnis wie die Ausführbare Datei zu legen.
    Ist so etwas auch mit einer .so Datei möglich???

    Nein, nicht standardmäßig. bei Unix/Linux kommt es ausschließlich darauf an, wie der LD_LIBRARY_PATH gesetzt ist. Wenn die Working-Directory (sprich aktueller Pfad) gesetzt ist, wie z.B.:

    LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH
    

    dann wird z.B. die shared Library ausschließlich im aktuellen Pfad gesucht.

    Normalerweise wird LD_LIBRARY_PATH aber etwa so gesetzt:

    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/myPath/lib:/usr/yourPath/lib; export LD_LIBRARY_PATH
    

    Da kann man natürlich auch ":." anfügen, das ist aber eher unüblich. Libraries stehen normalerweise in festen Directories (ggf. auch user-spezifisch unterschiedlich).

    Ansonsten gibt es auch noch das shell-Kommando ldconfig, mit dem man shared Libraries allgemein bekanntmachen kann, siehe hierzu http://www.linuxmanpages.com/man8/ldconfig.8.php. (Habe ich aber noch nie genutzt 😉 Die Bekanntmachung mittels LD_LIBRARY_PATH ist allgemein üblicher.



  • ja wenn du den gcc noch diese paramter gibst -Wl,-rpath,./sharedlibs/
    ./sharedlibs/ kann dann auch . sein oder ein ganz andere path



  • Gerard schrieb:

    ja wenn du den gcc noch diese paramter gibst -Wl,-rpath,./sharedlibs/

    ... ich befürchte leider, dass das spezifisch für den gcc ist und nicht für andere C-Compiler gilt 😢



  • ich hab kürzlich experimentiert mit ner main() in der lib.
    die main macht einen selbsttest über alle elemente der lib. wenn ich dann die lib einfach so zu ner exe linke, kommt der selbsttest raus, wenn ich sie aber zu irgend ner anderen main benutze, wird die main der lib gar nicht benutzt.
    die experimente sind nicht abgeschlossen, aber vermutlich wirds auf einen schwachsinnsfaktor von 80% rauslaufen. mal sehen.



  • supertux schrieb:

    ich habe aber ehrlich gesagt, noch keine Bibliothek gesehen, die so etwas benutzt.

    Der Boost Program Execution Monitor (Boost Test Framework) benutzt sowas. Die main der Bibliothek ruft die cpp_main der Anwendung auf und verfasst am Ende einen Bericht über geworfene Exceptions oder Returncode der cpp_main.


Anmelden zum Antworten