Forum: Compiler & IDEs dlopen bringt nichts!


von Matthias R. (mons)


Lesenswert?

Hallo,
ich habe versucht, opencv als dynamic library zu laden..
1
    void *opencv_main;
2
    void *opencv_highgui;
3
    void *opencv_imgproc;
4
    void *opencv_objdetect;
5
6
    opencv_main = dlopen("/usr/lib/opencv_core.so", RTLD_LAZY);
7
    opencv_highgui = dlopen("/usr/lib/opencv_highgui.so", RTLD_LAZY);
8
    opencv_imgproc = dlopen("/usr/lib/opencv_imgproc.so", RTLD_LAZY);
9
    opencv_objdetect = dlopen("/usr/lib/opencv_objdetect.so", RTLD_LAZY);

Wenn ich das Programm aber mit "gcc -rdynamic -ldl -o test main.c 
addid.c"
kompilieren will, bekomm ich link fehler mit "undefined reference"..
Genau dies sollte dlopen() doch deaktivieren??

von Dumdi D. (dumdidum)


Lesenswert?

Der Programmauschnitt den Du postest ist doch garantiert nicht der, der 
einen Fehler erzeugt. Bitte:

- Ein komplettes, kürzestmögliches Programm das den Fehler reproduziert 
erstellen und hier (komplett) posten
- Diesen Artikel und insbesondere das Beispiel lesen: 
http://linux.die.net/man/3/dlopen

von Matthias R. (mons)


Lesenswert?

Hier ein Blindcode, meinen eigentlichen Quellcode kann ich nicht 
veröffentlichen ;)
1
/* Blindcode 
2
 ***********************/
3
4
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <opencv/cv.h>
8
#include <opencv/highgui.h>  
9
#include <dlfcn.h>
10
11
int main(void) {
12
  
13
   //Libs laden
14
   void *opencv_main;
15
   void *opencv_highgui;   
16
   opencv_main = dlopen("/usr/lib/opencv_core.so", RTLD_LAZY);
17
   opencv_highgui = dlopen("/usr/lib/opencv_highgui.so", RTLD_LAZY);
18
19
   
20
    // Opjekt für Webcam initialisieren
21
    CvCapture *capture = 0;
22
    
23
    // Webcam öffnen
24
    capture = cvCaptureFromCAM(webcam);
25
    
26
    //überprüfen, ob die Webcam korrekt angesprochen wurde
27
    if (!capture) 
28
    {
29
      fprintf(stderr, "!!! Cannot open initialize webcam!\n" );
30
      return;
31
    }
32
33
    //Fenster erstellen
34
    cvNamedWindow("test", CV_WINDOW_AUTOSIZE);
35
36
    // Frame definieren 
37
    IplImage* frame = 0;
38
39
    while (key != 27) 
40
    {    
41
      // Webcam auslesen und Erbegnis in frame speichern
42
      frame = cvQueryFrame(capture);
43
      
44
      // Auf Fehler prüfen
45
      if(!frame) 
46
      {
47
          fprintf( stderr, "!!! cvQueryFrame failed!\n" );
48
          break;
49
      }
50
51
      cvShowImage("test", frame);
52
53
      key = cvWaitKey(10);
54
   }

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Und du bist dir sicher, dass du überhaupt selbst ein dlopen()
ausführen willst?  Oder willst du nicht einfach dynamische
Bibliotheken linken?  Am Ende geht das zwar auch über dlopen(),
aber das macht dann der run-time loader, und der füllt die
entsprechenden dynamischen Symbole auf, sodass du sie in deiner
Quelle direkt benutzen kannst.  Wenn du das dlopen() selbst machen
willst, darfst du natürlich noch keine direkten Referenzen auf
die dynamischen Symbole in deinem Programm haben (ich vermute mal,
Dinge wie cvQueryFrame() sind das, worüber sich dein Linker
beschwert), denn es ist ja noch gar nicht sicher, ob das shared
object dann überhaupt gefunden wird.  Den Symbolbezug kannst du
dann erst nach dem dlopen() herstellen.

Beispiele gibt's genug dafür, aber s. o., ich denke, dass das gar
nicht das ist, was du willst.  Du solltest dein opencv_gui.so in
libopencv_gui.so umbenennen und dann per -lopencv_gui einfach mit
linken lassen.

von ●● pit ●. (Gast)


Lesenswert?

bitte lerne erst, wie linken funktioniert.

vermutlich sollte es in deinem fall reichen, einfach -L und -l parameter 
beim kompilieren mitzugeben, das dlopen() brauchst du nicht.

und wenn du wirklich dlopen() machst, musst du die methoden, die du 
benutzen möchtest, dann erst mal mit dlsym() ein handle auf die funktion 
in der lib holen.

da kann man sich sehr einfach beispiele ergooglen.

von Matthias R. (mons)


Lesenswert?

Genau darum gehts ja ^^
Es funktioniert ja wenn ich sie mit -lopencv_core etc. linke!!
Es geht mir nur darum, dass ich das Programm auf meinem Raspberrypi für 
x86_64 und i686 (toolchains mit ct-ng gebaut) cross compilieren will und 
er bei einfachem kopieren der libs und header zum toolchain sysroot sich 
beschwert.

von Rolf Magnus (Gast)


Lesenswert?

Matthias R. schrieb:
> Es geht mir nur darum, dass ich das Programm auf meinem Raspberrypi für
> x86_64 und i686 (toolchains mit ct-ng gebaut) cross compilieren will

Du compilierst auf dem Raspberry-PI Code für den PC? Warum um aller Welt 
macht man denn sowas?

> und er bei einfachem kopieren der libs und header zum toolchain sysroot
> sich beschwert.

Ich wüßte jetzt nicht, wie man eine Verbindung zwischen dieser Aussage 
und der Notwendigkeit für dlopen() herstellen könnte.

Zu deinem Problem mit dlopen(): Wie schon erwähnt wurde: Du kannst nicht 
einfach Namen aus einer Bibliothek verwenden, an die du nicht linkst. 
Daran ändert auch dlopen() nichts.
Mit dlopen() öffnest du eine Bibliohthek zur Laufzeit, dann kannst du 
auf die darin enthaltenen Symbole zugreifen, indem du 
dlsym("symbolname") machst. dlsym() gibt dann einen Zeiger auf das 
entsprechende Symbol zurück.
Wenn du also cvNamedWindow aufrufen willst, mußt du dir erst per dlsym() 
einen Zeiger darauf holen und den Aufruf darüber machen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.