Formular unter DLL aufrufen
-
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ß dasvoid 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
*