externe DLL einbinden, Visual C++, struct in C



  • Hallo,

    wie schon geschrieben, habe ich leider einige Probleme beim Einbinden einer externen DLL in eine Visual C++ Application. Es handelt sich hierbei um eine angepasste Installation von einem Tut für Visual Studio angepasst an die aktuelle VLC-API 0.9.8a:
    http://doc.qtfr.org/post/2007/02/21/Integration-de-VLC

    Nachdem ich nicht den kompletten Code pasten möchte, habe ich den mal gezippt hinterlegt: http://blank.maringer-it.de/cplusplus/struct_libvlc.zip

    Die entscheidenden Teile poste ich mal hier. Es gibt eine main, die die Headerdatei der Klasse Player integriert:

    #include "vlc_on_qt.h"
    #include <vlc/vlc.h>
    #include <QtGui/QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Player p;
        p.resize(640,480);
        //p.playFile(".\\t_ninjagaidensigma_exclusive_h264.mov");
        p.show();
        return a.exec();
    }
    

    Im Konstruktor wird die Struktur libvlc_exception_t, die in der Headerdatei als Pointer definiert wird

    libvlc_exception_t *_vlcexcep;
    

    initialisiert:

    libvlc_exception_init(_vlcexcep);
    

    Die Struktur wird Folgendermaßen definiert:

    # ifdef __cplusplus
    extern "C" {
    # endif
    ...
    typedef struct libvlc_exception_t
    {
        int b_raised;
        int i_code;
        char *psz_message;
    } libvlc_exception_t;
    ...
    # ifdef __cplusplus
    }
    # endif
    

    Die Funktion "libvlc_exception_init" ist definiert als

    # ifdef __cplusplus
    extern "C" {
    # endif
    ...
    VLC_PUBLIC_API void libvlc_exception_init( libvlc_exception_t *p_exception );
    ...
    # ifdef __cplusplus
    }
    # endif
    

    Und in der Lib ist es definiert als:

    void libvlc_exception_init( libvlc_exception_t *p_exception )
    {
        p_exception->b_raised = 0;
        p_exception->psz_message = NULL;
    }
    

    So, viel Einführung, jetzt zu dem Problem. Ich kann das alles ohne weitere Probleme in VS08 kompilieren, ich kann es auch debuggen, ohne dass es Probleme gibt. Soweit ok, nur wenn ich es als Release kompiliere und da ausführe bekomme ich einen Laufzeitfehler. Beim Debug sieht es so aus, als wenn er auf einen Speicher zugreift, der so nicht vorhanden ist, bzw. der nicht den erwarteten Inhalt hat. Ich nehme weiterhin an, dass das mit dem Pointer in der Struktur zu tun haben könnte. Mein Versuch, einen Speicher über

    _vlcexcep = (struct libvlc_exception_t *) malloc(sizeof( struct libvlc_exception_t));
    

    zu allokieren, schlug leider fehl.
    Wenn ich wiederrum den Funktionsaufruf "libvlc_exception_init" weglasse, kann ich das Programm ohne Probleme als Release ausführen.

    Über jeglichen Tipp bzw. Hinweis bin ich dankbar, ich gebe zu, noch nicht allzulange mit C++ zu tun zu haben, also sicherlich noch einige Anfängerdenkfehler zu haben. Hatte vorher mit Java zu tun.

    Gute Nacht

    Alexander

    Nachtrag: VLC baut auf dem C99 Standard auf. (die stdint.h habe ich mir von einem Link des engl. Wikipedia geholt)

    Nachtrag 2: Der FAQ-Eintrag bestätigt meine Überlegung in Bezug auf die Speicherallokation, löst aber mein Problem noch nichr.


  • Mod

    Du kannst auch Debug Infos für die Release Version erzeugen und debuggen.
    Hast Du evtl. ein anderes packing der Strukturen (Alignment)?

    Wen Du einen Zeiger übergeben musst, dann ist dazu nicht unbedingt ein malloc notwendig.
    Das sollte genügen:

    struct libvlc_exception_t ex;
    libvlc_exception_init(&ex);
    

    Ich vermnute eher, dass Du die LIB falsch verwendest wenn eine globale Variable wir _vlcexcep NULL ist bzw. nicht initialisiert ist und sie verwendet wird.



  • Danke schonmal Martin für den ersten Tipp.

    Ich hatte doch glatt vergessen, reinzuschreiben, dass ich das schon so hatte, wie Du es vorgeschlagen hast, außer, dass bei mir das Wort struct fehlte.

    Du fragst, wie ich die Lib eingebunden habe? In dem VLC-Paket gibt es ein sdk, das im Include die Header-Dateien beinhaltetund in der lib folgende Dateien:
    - libvlc.def
    - libvlc.dll.a
    - libvlc.la

    Ich hatte irgendwo im Web gelesen, dass es ausreicht, die dll.a in dll.lib umzubenennen und einzubinden. Und ansonsten ist die dll im PATH.

    Deine Sache mit dem Debug habe ich leider so nicht ganz nachvollziehen können. Wenn ich im VS unter Linker -> Debugging -> Debuginfo generieren auf Ja setze, dann läuft auch das Release ohne Fehler ab.

    Vielleicht muss ich noch erwähnen, dass die VLC-Dateien mit dem Mingw kompiliert wurden. Aber nachdem ich ja nur eine Lib einbinden will, sollte das doch eigentlich keine Probleme geben.

    Deine Stichpunkte mit dem Alignment sagen mir so auch nichts und werde ich mal googeln müssen.

    Den Fehler, den das OS wirft (Win XP SP3) lautet:
    Fehlgeschlagene Anwendung vlc_on_qt.exe, Version 0.0.0.0, fehlgeschlagenes Modul unknown, Version 0.0.0.0, Fehleradresse 0x00905a4d.
    Das deutet ja eindeutig auf ein Speicherproblem hin (meines Erachtens)

    Danke Euch schon mal im Voraus

    Nachtrag: es gibt da ein nettes Tool ... den Dependency Walker. Der sagt mir, dass die DWMAPI.dll nicht gefunden werden konnte, aber die ist doch normal nicht für den Laufzeitfehler (Speicherzugriffsfehler) zuständig

    Nachtrag2: Nach Lesen Deines Blogs hoffe ich noch nicht zu den sogenannten Code Monkeys zu gehören, da ich ja versuche, das Problem selber zu lösen. Ach ja, der Versuch, das Problem über eine selber geschriebene Klasse zu lösen, die sich die struct aus einer Header-Datei holt, ist daran gescheitert, dass hierbei das Problem nicht auftritt. Es muss also tatsächlich etwas mit der Einbindung der Klasse zu tun haben oder aber mit den verschiedenen Compilern.

    Nachtrag3: Es gibt eine Linker-Warnmeldung:
    1>libvlc.lib(d000019.o) : warning LNK4078: Mehrere .text-Abschnitte mit unterschiedlichen Attributen gefunden (E0300020).

    Nachtrag 4: Bezieht sich auf Nachtrag 1. An der DWMAPI kann es nicht liegen, denn ohne dem Init kann ich die App ohne Laufzeitfehler ausführen.

    Nachtrag 5: Der Dependency Walker zeigt mir keine Abhängigkeit von der libvlc.dll, die er eigenltich haben sollte.



  • Es scheint, als seien die Lib's und Header-Dateien in Ordnung.
    Der Fehler mit der DWMAPI.dll ist ein Standard unter XP. Die tritt nur in Vista auf.

    Es tritt trotzdem keine Abhängigkeit zu den libvcl und libvlccore auf, was eigentlich sein sollte bzw. unter mingw ist dies der Fall.

    Meines Erachtens habe ich die Libs richtig eingebunden, zu mindestens ist mir kein anderweitiges Beispiel bekannt aus I-Net und 2 Büchern.

    Es könnte sehr wahrscheinlich etwas mit dem Stack-Alignment unter MSVS zu tun haben, aber das ist mir momentan noch zu hoch.

    Meine Alternative lautet in diesem Fall die IDE zu wechseln und alles unter Mingw mal zu compilieren, da treten ja die Fehler nicht auf.

    Eine Frage bleibt trotzdem offen ... mit welchen Einstellungen kann ich das Release an sich debuggen.

    Gute Nacht

    Ein nach vielen Stunden Fehlersuche etwas übermüdeter Alex


Anmelden zum Antworten