000
25.01.2007, 11:28 Uhr
J-jayz-Z
Perl Crack ala Carte (Operator)
|
Ich hab ich gestern mal mit shared Libraries unter Linux beschäftigt und wie man diese erzeugt. Mein Wissen wollte ich nur mal mit anderen teilen und dies hier zu Besten geben. Anmerkungen sind natürlich willkommen.
Shared Libararies (*.so) sind kompilierte *.cpp Dateien, die eine Sammlung von Funktionen enthalten. Shared Libraries entsprechen *.dll's unter Windows und sind unter Linux sehr weit verbreitet. Diese Libraries befinden sich normalerweise in dem Ordner /usr/lib/ und beginnen mit lib*. Die Endung ist meistens .so.1.0 oder ähnliches,wobei die zahlen nach dem .so die Version der Library zeigen sollen. Die aktuellste Version ist meist mit der gewöhnlichen .so Datei verlinkt.
Nun mal ein kleines Beispiel. Natürlich kein sinnvolles, es soll nur zeigen, wie der Ablauf ist um eine solche Library zu erzeugen.
Die hello.hpp Datei:
C++: |
#ifndef TEST_INCLUDED #define TEST_INCLUDED class Test { public: Test(); void printMe(); }; #endif
|
Die hello.cpp Datei:
C++: |
#include <iostream> #include "hello.hpp"
Test::Test() { std::cout << "Konstruktor" << std::endl; }
void Test::printMe() { std::cout << "Hello World" << std::endl; }
|
Nun kompilieren wir die hello.cpp Dateimit folgendem g++ Aufruf:
Code: |
g++ -fPIC -c hello.cpp
|
Und linken die Datei wie folgt:
Code: |
g++ -shared -o libhello.so hello.o
|
Nun haben wir die Datei libhello.so und versuchen diese nun in unser Programm einzubinden
main.cpp
C++: |
#include <iostream> #include "hello.hpp"
int main(int argc, char* argv[]) { Test foo; foo.printMe(); return EXIT_SUCCESS; }
|
Nun nur noch kompilieren und fertig ...
Code: |
g++ -o main main.cpp -L. -lhello
|
Und noch ausführen zum Testen
Code: |
user@host~>./main ./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
|
Das liegt daran, das es eben eine shared Library ist. Diese wird erst bei der Nutzung geladen. Beim kompilieren ist das kein Problem, wenn man mit -L. angibt, das sich die lib im aktuellen Verzeichniss befindet, man kann sich jedoch nicht immer darauf verlassen ...
Jetzt haben wir mehrere Möglichkeiten. Entweder wir passen LD_LIBRARY_PATH so an, das es die Datei auch findet
Code: |
export LD_LIBRARY_PATH=.:${LD_LIBRARY_PATH}
|
Und fürhen die Datei aus:
Code: |
user@host~>./main Konstruktor Hello World
|
Oder wir verschieben die lib nach /usr/lib/ - dann ist sie auch gleich für alle sichtbar. Den in dieses Verzeichniss gehören lib's normalerweise auch. Aber die letzte und "richtigste" Möglichkeit wäre, sie in die /etc/ld.so.conf einzutragen. In dieser Datei stehen die Verzeichnisse in denen die .so bei der Ausführung gesucht werden.
In diese Datei fügen wir jetzt Testweise auch einfach das aktuelle Verzeichniss (.) hinzu.
Code: |
echo "." >> /etc/ld.so.conf
|
Danach müssen wirnoch ldconfig ausführen - un et voila. Ein erneutes ausführen von main zeigt uns, das alles so verlaufen ist, wie es sollte.
Zum Abschluß mal noch die Ausgabe von ldd auf main angewandt:
Code: |
user@host~>ldd main linux-gate.so.1 => (0xffffe000) libhello.so => ./libhello.so (0x40018000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40023000) libm.so.6 => /lib/tls/libm.so.6 (0x400ff000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40125000) libc.so.6 => /lib/tls/libc.so.6 (0x40130000) /lib/ld-linux.so.2 (0x40000000)
|
Sooo - viel Spaß damit -- perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"' Dieser Post wurde am 25.01.2007 um 11:29 Uhr von J-jayz-Z editiert. |