Formular unter DLL aufrufen



  • Hallo zusammen, ich hoffe mir kann jemand helfen mit meinem Problem. Ich suche nach einer Möglichkeit, wie ich unter Borland C++ Builder eine Klasse aus einer DLL an eine Anwendung übergeben kann. Um genauer zu sein, beinhaltet die DLL ein Formular das von einer Anwendung die dieses DLL lädt aufgerufen werden kann. Ich weis, dass das zur Verfügung stellen von Oberflächen durch DLLs nicht unbedingt üblich ist, trotzdem muss ich das so hinbekommen.
    Hat jemand etwas Zeit mir dabei zu helfen?
    *
    Mit freundlichen Grüßen
    coder24h
    *



  • Hallo

    schau dir das Builder-Tutorial dieses Forums an, insbesondere diesen Abschnitt.

    bis bald
    akari



  • Super! Ich werde das sofort ausprobieren!

    Vielen, vielen Dank akari!
    coder24h



  • Ich habe ein weiteres Problem: Die DLL sollte dabei explizit bzw. dynamisch geladen werden! So habe ich das Probiert, hat aber nicht funktioniert:

    __declspec(dllimport) void FormShow(TComponent* Owner);
    
    //---------------------------------------------------------------------------
    __fastcall TfrmMain::TfrmMain(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::btnLoadDLLClick(TObject *Sender)
    {
    	HINSTANCE h = LoadLibrary("TestDLL01.dll");
        if (!h)	ShowMessage("Die DLL 'TestDLL01.dll' konnte nicht geladen werden");
        else
        {
    		FormShow(Application);
        }
    }
    //---------------------------------------------------------------------------
    

    Folgender Fehler wird ausgegeben:

    [Linker Fehler] Unresolved external 'FormShow(Classes::TComponent *)' referenced from D:\C++\BORLAND C++ 6\TESTDLL01LOADER\UNITFRMMAIN.OBJ
    


  • Hallo

    Du hast nun statisches und dynamisches Linken vermischt.
    Du must noch GetprocAddress benutzen, siehe hier.

    bis bald
    akari



  • Ich bin die ganze Zeit am machen, kriege aber das Ganze nicht ans laufen. Hat vielleicht jemand ein fertiges Beispiel damit ich den mit meinem vergleichen kann?

    In der DLL habe ich folgendes stehen:

    //---------------------------------------------------------------------------
    extern "C" __declspec (dllexport) void OpenForm(TComponent* Owner)
    {
        TFormMain* FormMain = new TFormMain(Owner);
    	FormMain->ShowModal();
    }
    

    In der Anwendung die diese DLL nutzt das hier:

    typedef void TOpenForm(TComponent); // Typ für eine Funktion aus der DLL-Unit
    void OpenForm(TComponent* Owner);
    
    //---------------------------------------------------------------------------
    void OpenForm(TComponent* Owner)
    {
        TOpenForm* OpenForm; //Zeiger auf ein Funktionsdatentyp
    
        HINSTANCE h = LoadLibrary("TestDLL01.dll"); //DLL wird bei Bedarf geladen
    
        if (h != 0)
        {
        	OpenForm = (TOpenForm*)GetProcAddress(h, "_OpenForm");
            ShowMessage("DLL geladen");
        }
        if (OpenForm != NULL)
        {
            ShowMessage("Funktion ausgeführt");
            OpenForm(NULL);
    
        }
        //FreeLibrary(h);
    
    }
    


  • Hallo

    Das Verlinkte Beispiel ist fertig.
    Bei dir muß das

    void OpenForm(TComponent* Owner);
    

    aus der Anwendung die die DLL nutzt raus.

    Ansonsten :

    kriege aber das Ganze nicht ans laufen

    ist keine Ausreichende Fehelrbeschreibung!

    bis bald
    akari



  • Ich kann mir das nicht erklären und hoffte einfach nur, dass im diesen übersichtlichen Code der Fehler entdeckt wird. Ich kriege einfach die Anwendung nicht kompiliert:

    Fehlermeldung:

    [C++ Fehler] UnitFormMain.cpp(31): E2459 Klassen im VCL-Stil müssen mit dem Operator new erstellt werden
    

    entsteht an der Stelle

    OpenForm(NULL);
    

    😢



  • Hallo

    typedef void TOpenForm(TComponent*);// Zeiger
    

    bis bald
    akari



  • Danke akari für deine tatkräftige Unterstützung! Jetzt bin ich zwar weiter es scheint aber noch nicht auszureichen.

    Ich komme im diesen Block nie an:

    if (OpenForm != NULL)
        {
            ShowMessage("Funktion ausgeführt");
            OpenForm(NULL);
        }
    


  • Hallo

    dann stimmt der angegebene Name hier nicht

    OpenForm = (TOpenForm*)GetProcAddress(h, "_OpenForm");
    

    las mal den Unterstrich weg.

    bis bald
    akari



  • Wenn ich meine DLL aus dem C++ Builder starte bzw. kompiliere, wird dabei automatisch die Anwendung die diese DLL nutzt aufgerufen. Diese Anwendung funktioniert dabei reibungslos!

    Wenn ich jedoch die Anwendung selber ausführe, findet diese die Funktion OpenForm nicht! Ich habe scheinbar noch irgendwo einen Fehler 😢

    Unter DLL:

    #pragma argsused
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
    {
    	return 1;
    }
    
    //---------------------------------------------------------------------------
    extern "C" __declspec (dllexport) void OpenForm(TComponent* Owner)
    {
        TFormMain* F = new TFormMain(Owner);
    	F->ShowModal();
    }
    

    Unter Anwendung:

    typedef void TOpenForm(TComponent* Owner); // Typ für eine Funktion aus der DLL-Unit
    
    void OpenForm(TComponent* Owner)
    {
        TOpenForm* OpenForm = NULL;  //Zeiger auf ein Funktionsdatentyp
    
        HINSTANCE h = LoadLibrary("TestDLL01.dll"); //DLL wird bei Bedarf geladen
    
        if (h != 0)             // Prüfen ob die DLL geladen worden ist
        {
            OpenForm = (TOpenForm*)GetProcAddress(h, "_OpenForm"); // Zeiger auf die
                                                       // Funktion aus in der setzen
            ShowMessage("DLL geladen");
        }
        if (OpenForm != NULL)   // Prüfen ob der Zeiger auf eine Speicherstelle zeigt
        {
            ShowMessage("Funktion ausgeführt");
            OpenForm(NULL);     // Funktion aus der DLL ausführen
        }
    
       // FreeLibrary(h);         // Instance wieder freigeben, erst wenn
                                  // nicht mehr benötigt
    
    }
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	OpenForm(NULL);         // Funktion ausführen
    }
    

    Kann hier jemand erkennen woher so ein Verhalten kommen kann?
    MfG coder24h
    😕 😕 😕



  • Hallo

    wird denn beim zweiten Fall überhaupt die DLL selber gefunden?

    bis bald
    akari



  • Das ist ja das komische, die DLL wird gefunden! Das wird mir auch durch die

    ShowMessage("DLL geladen");
    

    bestätigt.



  • Hallo

    Las mal sowohl DLL als auch Anwendung komplett neu erstellen (Menü Projekt/Alle Projekte erstellen, wenn du beides in einer Projektgruppe hast)

    bis bald
    akari



  • Danke sehr akari, du hast mir sehr bei meinem Problem geholfen. Nach dem Neuerzeugen der Projektgruppe funktioniert jetzt alles wie erwünscht.
    *
    Vielen, vielen Dank!
    coder24h
    *👍 😮


Log in to reply