Froma us DLL in EXE app aufrufen



  • hi,

    wie genau muss ich da vorgehen? hier gibt es zwar ein paar beiträge zum thema DLL aber die helfen mir nicht wirklich. was ich machen will, sit, eine form die in einer DLL ist, von einer normalen anwendung (EXE) aufrufen.

    das DLL projekt wurde unverändert belassen wie es der BCB projektmanager erstellt hat. VCL ist aktive. nun habe ich dem projekt ein neues formular hinzugefügt und das wars dann.

    jetzt möchte ich eben aus der anwendung (EXE) das fenster der DLL aufrufen. wie geht das genau? zuerst denke ich mal sowas wie:

    HINSTANCE DLL = LoadLibrary("datei.dll");
    if(DLL != NULL)
    {
        //zeuge Form2 der DLL........
    }
    

    jetzt eben wie die form2 anzeigen lassen und wann muss man FreeLibrary verwenden? Nachdem die hauptanwendung sich beendet? z.b. OnClose() ?





  • hm danke. also brauch ich garkein LoadLibrary mehr? und was bedeutet DLL_TYP? was muss da hin?

    class DLL_TYP TForm1 : public TForm



  • Einfach mal die ganze Seite lesen



  • also __export. jetzt bekomme ich aber eine zugriffsverletzung.
    im hauptprogramm habe ich eine funktion die selber exportiert wird. in dieser funktion wird bei aufruf dann die form2 einer dll aufgerufen. doch da krieg ich eben eine zugriffsverletzung.

    //diese funktion wird exportiert und aufgerufen bevor die anwendung startet.
    void __declspec(dllexport) __stdcall GetTrialDays(int Total, int Left)
    {
        //hier dann die form2 einer dll aufrufen.	
        TdllForm *dllform = new TdllForm(Application);
        dllform->ShowModal();
    }
    


  • Hallo

    Der Form-Aufruf sollte besser so aussehen

    TdllForm *dllform = new TdllForm(NULL);
    dllform->ShowModal(); 
    delete dllform;
    

    Ansonsten Debugger benutzen und schauen, an welcher Stelle die Exception genau kommt.

    bis bald
    akari



  • zugriffsverletzung bei: 0x7c9477c9
    schreiben von adresse: 0x00030fe8

    daraus werde ich jetzt aber nicht schlau. und wieso muss der speicher gleich wieder freigegeben werden? die form wird ja benötigt aber wenn ich den speicher unmittelbar nach dem erzeugen des objektes wieder freigebe, existiert ja der speicherbereich nicht mehr 😕



  • dll_omg schrieb:

    daraus werde ich jetzt aber nicht schlau. und wieso muss der speicher gleich wieder freigegeben werden? die form wird ja benötigt aber wenn ich den speicher unmittelbar nach dem erzeugen des objektes wieder freigebe, existiert ja der speicherbereich nicht mehr 😕

    überlege dir mal was der unterschied zwischen

    Form->Show();
    

    und

    Form->ShowModal();
    

    ist

    mfg
    BigNeal



  • Hallo

    und wieso muss der speicher gleich wieder freigegeben werden? die form wird ja benötigt aber wenn ich den speicher unmittelbar nach dem erzeugen des objektes wieder freigebe, existiert ja der speicherbereich nicht meh

    - du rufst ShowModal() auf. Das Form öffnet sich dann und hält das Programm so lange an, bis dieses wieder geschlossen wird. Danach kann i.a. die Form-Instanz auch wieder gelsöcht werden, ein neuer Aufruf des Forms benötigt ja eh ein Aufruf der Funktion mit dem erstellen einer neuen Instanz.

    Wenn du dort kein delete machst, hängt deine Form-Instanz im leeren Raum und erzeugt ein Speicherloch, da der einzigste Pointer mit der Adresse ja eine lokale Variable der Funktion ist und nach der Funktion verfällt.

    bis bald
    akari



  • ok danke das macht sinn. jedoch weiss ich trotzdem nicht warum ich eine zugriffsverletzung bekomme 😕 hier noch der code der dll klasse.

    //---------------------------------------------------------------------------
    
    #ifndef CaxH
    #define CaxH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class __export TdllForm : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
    	__fastcall TdllForm(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TdllForm *dllForm;
    //---------------------------------------------------------------------------
    #endif
    


  • Hallo

    Debugger benutzten und die genaue Zeile finden, an der die Exception vorkommt. Das muß an einer speziellen Anpassung von dir liegen, das Verfahren an sich ist korrekt.

    bis bald
    akari



  • der debuger hält an der zeile

    TdllForm *dllform = new TdllForm(NULL);
    

    an. und nun? 😕
    muss sonst am dll projekt noch was getan werden? z.b. am einprungspunkt oder so? dieser ist original wie vom projektmanager erstellt.



  • Wo tritt die Zugriffsverletzung denn genau auf?
    Im Programm oder in der DLL?
    Und in welcher Funktion?
    Was passiert an der Stelle an der die Zugriffsverletzung ausgelöst wird?

    Entschuldigung, da war jemand schneller!



  • ich hab alle informationen die mir bekannt sind (inkl. code) gesagt. mehr weiss ich nicht. insofern kann ich nichts zu deinem post sagen.



  • ich hab alle informationen die mir bekannt sind (inkl. code) gesagt. mehr weiss ich nicht. insofern kann ich nichts zu deinem post sagen.



  • kann mir sonst einer ein beispielprojekt einer dll und einer exe anwendung machen und hier von beiden den code posten? dann sehe ich eher was ich falsch gemacht habe.



  • hier ein neues projekt von mir:

    exe - .cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include "DLL.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	TfrmDLL *dll = new TfrmDLL(NULL);
        dll->ShowModal();
        delete dll;
    }
    //---------------------------------------------------------------------------
    

    exe - .h
    nichts - da unverändert.

    dll - .cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    //---------------------------------------------------------------------------
    
    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    	return 1;
    }
    //---------------------------------------------------------------------------
    

    dll - .h

    //---------------------------------------------------------------------------
    
    #ifndef DLLH
    #define DLLH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class __export TfrmDLL : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
    	__fastcall TfrmDLL(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TfrmDLL *frmDLL;
    //---------------------------------------------------------------------------
    #endif
    

    Weiteres
    Dem exe projekt wurde die *.lib der dll datei hinzugefügt.

    Problem
    Wie beschrieben, zugriffsverletzung



  • class __export TfrmDLL : public TForm
    

    So geht das auch nicht:

    Funktionen/Klassen einer DLL müssen ex- bzw. importiert werden. Da du offenbar das

    #ifdef __DLL__
    #	define DLL_TYP __declspec(dllexport)
    #else
    #	define DLL_TYP __declspec(dllimport)
    #endif
    

    nicht nutzen willst / nicht gelesen hast, brauchst du 2 Header Dateien für dein DLL Formular

    Der erste ist für das Compilieren und Linken der DLL und exportiert die Klasse.

    Die zweite ist für das Compilieren und Linken der EXE un importiert die Klasse.

    Mit obigen Code kannst du dir das ersparen un eine Header Datei für beide Vorgänge nutzen.



  • verstehe dich nicht ganz. wie genau muss ich mein beispiel nun anpassen und was genau muss ich dann an dateien noch verwenden? 🙄



  • ich glaube ich verstehe dich nun. logisch ist natürlich das exe import muss und dll export. deswegen ging es ja nicht wie du sagst, mit dem __export ohne define makro. jedoch klappt das ganze nicht so ganz. im dll header (der dann auch im exe projekt so verwendet wird) steht das nun:

    //---------------------------------------------------------------------------
    #ifndef DLLH
    #define DLLH
    
    #ifdef DLLH
    #define DLL __declspec(dllexport)
    #else
    #define DLL __declspec(dllimport)
    #endif
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class DLL TfrmDLL : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
    	__fastcall TfrmDLL(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TfrmDLL *frmDLL;
    //---------------------------------------------------------------------------
    #endif
    

    ist das korrekt so?



  • scheinbar muss ich den gleichen header für das exe projekt noch ohne den anfang benutzen, also so:

    //---------------------------------------------------------------------------
    #ifdef DLLH
    #define DLL __declspec(dllexport)
    #else
    #define DLL __declspec(dllimport)
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    class DLL TfrmDLL : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
    	__fastcall TfrmDLL(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TfrmDLL *frmDLL;
    //---------------------------------------------------------------------------
    #endif
    

    stimmt das nun alles?


Anmelden zum Antworten