Klasse aus DLL importieren...
-
HI Martin,
erstmal danke für die Antwort... ich glaube da hat ich dich missverstanden... ich dachte du möchtest gar keien DLL mehr verwenden sondern meintest ich solle direkt alle Klassen in das eine Projekt laden

Nun gut... also das was du da beschreibst ist eigentlich das was ich letztendlich vor habe... aber irgendwie... naja es klappt nicht so ganz :)...
Irgendwie kann ich kein Objekt erzeugen... bzw. hab ich auch immer noch diese DumpObjekt Fehlermeldung :(...
Gibt es ein Beispiel für solch ein Projekt irgendwo? Ein kleines übersichtliches?! :)... ich habe dieses Beispiel in der MSDN "dllhusk" gefunden... aber ist das, dass was ich brauche?
Danke für Antworten!
-
Was meinst Du, du kannst kein Objekt erzeugen. Wie machst Du es denn?
-
Naja bis jetzt so wie ich es am Anfang beschrieben habe... ich lade die DLL über
::AfxLoadLibrary("DLLTest.dll");Danach habe ich nun also die DLL geladen... aber ich kann jetzt kein Objekt der Klasse TestButton erzeugen... weil der Compiler diese Klasse nicht kennt (sie ist ja in der DLL definiert).
Also bin ich jetzt deinen Weg gegangen und habe versucht das Interface in der DLL zu verwenden und eine Create und etc. Funktion zu schreiben in der DLL... Die würde ich dann nacher aufrufen und dann eben die über die Schnittstelle verwenden (die kennt ja mein Hauptprogramm)... wie komme ich denn nun an die Create etc dran mit
GetProcAddress(m_hViewDll, "Create");Ich werde über meine Misserfolge weiter berichten und versuche es erstmal so... schrei laut falls das alles blödsinn ist

-
Hast Du sicher die Klasse auch per DYNCREATE deklariert und verwendest Du CRuntimeClass::CreateObject um das Objekt zu erzeugen?
Wenn Du eine Factory Funktion verwenden willst besorgst Du dir die entsprechenden Funktionszeiger per GetProcAddress. Vergiss nicht eine Versionierung vorzusehen!
-
Hallo Martin und auch hallo der Rest...
ich verzweifle gerade... also ich hab jetzt folgendes in eine DLL gepackt:
// FISButton.cpp : Definiert die Initialisierungsroutinen für die DLL. #include "../#header/GUIElement.h" #include "stdafx.h" #include <afxdllx.h> static AFX_EXTENSION_MODULE GUIElementDLL = { NULL, NULL }; extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { // Entfernen Sie dies, wenn Sie lpReserved verwenden. UNREFERENCED_PARAMETER(lpReserved); if (dwReason == DLL_PROCESS_ATTACH) { TRACE0("DLL wird initialisiert!\n"); // Einmalige Initialisierung der Erweiterungs-DLL if (!AfxInitExtensionModule(GUIElementDLL, hInstance)) return 0; new CDynLinkLibrary(GUIElementDLL); } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0("DLL wird abgebrochen!\n"); // Bibliothek vor dem Aufruf der Destruktoren schließen. AfxTermExtensionModule(GUIElementDLL); } return 1; // OK } AFX_EXT_CLASS IGUIElement* Create() { TRACE("HALLO"); return NULL; }Der Header der gemeinsamen Schnittstelle GUIElement.h sieht so aus:
#include "stdafx.h" #ifndef GUIELEMENT_H #define GUIELEMENT_H // Klassen die in diesem Header deklariert werden class IGUIElement; // Klassendeklaration class IGUIElement abstract { public: IGUIElement() {}; virtual ~IGUIElement() {}; virtual BOOL Create(CWnd* pParent) = 0; virtual BOOL ReceiveInformation() = 0; virtual CString GetID() = 0; }; AFX_EXT_CLASS IGUIElement* Create(); #endifIm Hauptprogramm habe ich jetzt folgendes
HINSTANCE m_hViewDll; typedef IGUIElement* (CALLBACK* LPFNDLLFUNC1)(); ... BOOL CTHEApp::InitInstance() { m_hViewDll = NULL; m_hViewDll = ::AfxLoadLibrary("DLL/GUIElement.dll"); if (!m_hViewDll) AfxMessageBox("Error: Cannot find component \"GUIElement.Dll\""); LPFNDLLFUNC1 lpfnDllFunc1 = (LPFNDLLFUNC1) GetProcAddress(m_hViewDll, "Create"); if (!lpfnDllFunc1) { // handle the error AfxFreeLibrary(m_hViewDll); m_hViewDll = NULL; AfxMessageBox("FEHLER BEIM LADEN VON CREATE"); } else { // call the function IGUIElement* pTest = lpfnDllFunc1(); }Es kommt immer die Messagebox "FEHLER BEIM LADEN VON CREATE"...
Wieso? Ich hab alles hier gepostet glaube ich... ich hab nicht mehr... irgendwo muss da doch ein Fehler sein... ich hab außerdem noch immer dieses DumpObject...
Danke für jegliche Hilfe ...
ein verzweifelter Jogilein
-
Muss ich unter Umständen noch irgendwas in diese DEF-Datei eintragen?
Zur Zeit sieht der EXPORT-Bereich so aus:
EXPORTS ; Explizite Exporte können hier eingefügt werden.Soweit ich jedoch die MSDN verstehe... muss das nicht sein udn es reicht die Angabe von __declspec(dllexport)...
-
Die Anwort gibt Dir Depends.exe, da kanst Du sehen was wirklich exportiert wird.
Ohne DEF-Datei heißt der Export _Create und ist zusätzlich gemangelt.
Funktion Create als extern "C" definieren und in die Def-Datei eintragen.
-
Danke für die Antwort Martin werde ich ausprobieren... ist denn sonst so alles soweit richtig?!
Wieso bekomme ich die DumpObject-Meldungen am Ende... ich meine die DLL ist mit dem Assistenten generiert und trotzdem bekomme ich die

-
Inwieweit "zusätzlich gemangelt"?
-
Name mangeling ist die Art und Weise wie der C++ Compiler Symbole verschlüsselt, damit Sie der Linker versteht.
Hast Du ein Mini-Sample? Schick es mir per Email.
-
Hi Martin,
Hast Du ein Mini-Sample
Ich kann dir das ganze Projekt zippen bzw. die Mappe und dir mailen... ich hab da nicht wirklich was zu verstecken :)... aber es könnte ein bischen größer werden

Danke für das Angebot
JogileinPS: Ich warte noch auf deine Antwort, ob es ok ist...
-
HI Martin,
ich sehe gerade, dass das Paket nicht so groß ist (ohne Intellisense etc... nur 230KB)... ich schick es einfach mal

Nochmals danke für jede Anmerkung die du hast, sei es wegen schlechten Programmierstyles oder unmöglichen Konstruktionen

-
Ich bin eben erst dazu gekommen Dein Projekt anzusehen.
Erster Eindruck: Eine einzige Katastrophe.
Selbst wenn man Testcode baut, sollte er leserlich sein und die Indents stimmen.
Würdest Du in meiner Firma arbeiten und solchen Code (selbst als Testproject) schreiben, würde ich Dir auf die Finger klopfen...
Ich befürchte ja sogar das dieser Code direkt Produktiv-Code werden soll...- Das Memory Leak ensteht dadurch, dass Dein DLL und Deine EXE nicht das selbe MFC Projekt verwenden. EXE ist Multibyte, DLL ist UNICODE! Die beiden Projekte verwenden komplett unterschiedliche DLL Kerne.
- Du hast nicht auf mich gehört und die Create Funktion als extern "C" definiert.
- Du hättest Dir auch das Entwicklen leicher machen können, indem Du bei beiden Projekten ein identisches Ausgabevezeichnis angibst.
-
Erster Eindruck: Eine einzige Katastrophe.
Autsch...
Selbst wenn man Testcode baut, sollte er leserlich sein und die Indents stimmen.
Nur zu meiner Verteidigung :D... das mach ich nicht damit ich den Testcode schneller finden :)... schlechte Ausrede
...Ich befürchte ja sogar das dieser Code direkt Produktiv-Code werden soll...
Nein... es ist erstmal ein Test :)... aber ich würde schon später was feines daraus bauen :D...
Nun aber erstmal vielen Dank dafür, dass du dich durch dieses Chaos gekämpft hast :)...
Du hast nicht auf mich gehört und die Create Funktion als extern "C" definiert.
Mist... das hab ich mal wieder vergessen :(... aber die Create-Funktion kann ich nun aufrufen... Danke!
Das Memory Leak ensteht dadurch, dass Dein DLL und Deine EXE nicht das selbe MFC Projekt verwenden. EXE ist Multibyte, DLL ist UNICODE! Die beiden Projekte verwenden komplett unterschiedliche DLL Kerne.
Ich hab jetzt beide auf Multibyte umgestellt... aber der Leak ist noch immer da

Du hättest Dir auch das Entwicklen leicher machen können, indem Du bei beiden Projekten ein identisches Ausgabevezeichnis angibst.
Du meinst damit die DLL direkt im Verzeichnis der EXE liegt... Stimmt :D...
Also nochmals vielen vielen Dank Martin für die Hilfe und dafür das du dir den Code angeschaut hast... ich versuche mich in Sachen "Erster Eindruck" zu bessern :D... vielleicht findest du kurz Zeit einige Tipps zu geben... damit er leserlicher wird (Indents hab ich notiert).
Gruß
Jogilein
-
Bekomme nun folgendes bei der Ausgabe, zusätzlich zu den Memory Leaks... was bedeutet das?
Eine Ausnahme (erste Chance) bei 0x7c809e3a in FIS.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x10024dc0. #File Error#(51) : {147} client block at 0x00358B28, subtype c0, 104 bytes long. Eine Ausnahme (erste Chance) bei 0x7821f400 (mfc80d.dll) in FIS.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x10024f14. faulted while dumping object at $00358B28, 104 bytes long Object dump complete.
-
Habs gelöst :)... aber vielleicht könnte mir jemand erklären was die Fehlermeldung nun bedeutete :D...
Danke
-
Eine Ausnahme (erste Chance)
Hier wird eine Exception von einem Modul gworfen, aber diese wird auch behandelt. Der Debugger zeigt diese jedoch immer an. Schau mal in die FAQ da findest Du sicher was dazu. Siehe auch "First chance exception"
Ansonsten sende mir noch mal Dein Sample. Dann habe ich wieder was zu motzen...

-
Werde ich gleich sofort losschicken :)... und dann werde ich danach mal ein bischen darüber lesen... wobei er ja jetzt nichts mehr zu meckern hat und alles läuft...
Naja ansonsten hab ich jetzt alles schön in einzelne Libs gepackt und ein bischen versucht aufzuräumen, damit du nicht wieder zu sehr meckerst :D... Und ich habe es sogar geschafft, dass die einzelnen kompilierten Programme in ein Verzeichnis gehen und von dort aus dann auch ausgeführt werden können... ach ja und ich hab Abhängigkeiten gesetzt :)...
Ansonsten hätte ich noch eine Frage:
Gibt es für solch einen "Funktionsprototypen" (ich weiß nicht ob das die korrekte Bezeichnung ist) einen Notationsstandard für den Namentypedef IGUIElement* (CALLBACK* [b]LPFNDLLFUNC1[/b])();Ich meine sowas wie eine Membervariabel beginnt mit m_Name...
Gruß
Jogilein