Kurz nee fragende Anmerkung zum Thema Shared Objects in C++ unter Linux
Nachdem ich das schöne .so Beispiel "cosinus" in C zum laufen gebracht habe.
Hab ich mir ein Beispiel besorgt, das unter C++ kompiliert werden kann (in Kdevelop)
Nachdem ja in dem Cosinus Code die so-File direkt ohne ./ oder Verzeichniss angegeben wird,
dachte ich mir das geht auch ganz einfach mit ner selbst geschriebenen .so File.
Hier der Code vom Cosinus Beispiel:
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("libm.so", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
return 0;
}
Kompiliert wird das dann in der Console mit
gcc -rdynamic -o foo foo.c -ldl
Wie man sieht steht bei dlopen nur "libm.so" also weder "./libm.so" oder gar "/usr/lib/libm.so"
Das funktioniert ja, weil die libm.so in dem Library-Verzeichniss des Betriebssystem liegen
und das Programm dann während der ausführung automatisch in diesem Verzeichniss sucht.
Nun habe ich folgende File geladen
(siehe Anhang)
dann mit
tar zxvf examples.tar.tar
entpackt.
Wenn man sich den Quellcode main.cpp anschaut, sieht man folgende Zeile.
void* triangle = dlopen("./triangle.so", RTLD_LAZY);
d.h. die .so File muss sich also dann im lokalen Verzeichniss befinden in dem sich auch die Runfile befindet.
Nachdem ich alles kompiliert hatte (nicht mit dem mitgeliefertem Make, sondern als Projekt in KDevelop)
mit einem zusätzlichen Parameter -ldl (da er sonst mit dem dlopen usw total aussteigt)
(zu finden in KDevelop unter
Projekt-> Optionen -> Compiler Einstellungen->Linker Schalter->weiter Schalter und dort in dieses Feld -ldl eintragen
)
hatte er die Runfile erzeugt und eine File triangle.o
Diese .o File muss ich ja jetzt noch dynamic shared machen mit folgendem Befehl
g++ -rdynamic -shared -o triangle.so triangle.o
nun habe ich eine .so File....
nun will ich aber die .so File nicht im lokalen Verzeichniss haben, sondern wie die libm.so
(von oben) im /usr/lib Verzeichniss (Library Verzeichniss des Systems)
Da ich aber keine Root Rechte besitze in dieses Verzeichniss zu schreiben
erzeuge ich kurzerhand selbst ein Verzeichniss
/usr/usr/myaccount/mylibs/
und setze mit setenv den Library Path darauf
setenv LD_LIBRARY_PATH /usr/usr/myaccount/mylibs
eine Überprüfung mit env | grep LIB zeigt mir das der Pfad gesetzt wurde
wenn ich nun die .so File in das mylibs Verzeichniss verschiebe
und dann im Quellcode statt "./triangle.so" einfach "triangle.so" schreibe,
meldet er nachdem das Programm gestartet wurde, das er die Library nicht findet.
Was mach ich falsch?
bin hier echt am verzweifeln....
wieso funktioniert das mit der Standard Lib libm.so , aber mit der selbst geschriebenen im selbst gesetzten Lib-Verzeichniss nicht
danke schon mal für alle Infos
UFO
p.s. habe auch schon mal mittels
g++ -shared -Wl,-soname,triangle.so.1 -o triangle.so.1.0 triangle.cpp
mv triangle.so.1.0 /usr/myaccount/mylibs
mv triangle.so /usr/myaccount/mylibs
ln -sf /usr/myaccount/mylibs/triangle.so.1.0
ln -sf /usr/myaccount/mylibs/triangle.so
ln -sf /usr/myaccount/mylibs/triangle.so.1
Symbolisch links erzeugt...
d.h. im lokalen verzeichniss ist dann ein Link namens triangle.so der auf die /usr/myaccount/mylibs/triangle.so verlinkt
das mag er aber auch nicht... sondern nur wenn ich wieder "triangle.so" in "./trinangle.so" umändere dann funzt das Ding mit dem Link...
p.p.s. mein Ziel ist es... das die Libs einmal alle kompiliert werden und in ein Verzeichniss abgelegt werden, das als LD_LIBRARY_PATH gesetzt wird,
d.h. ich will keine Libs oder Verlinkungen drauf in meinem Programmverzeichniss liegen haben
Lesezeichen