[solved] Dynamisch eingebundene DLL schmeißt exceptions.
-
[quote="cl90"]niemand eine idee woran das liegt?[(quote]
Wenn fGet() so ist wie bla(), ist der Fehler sonneklar.Aber nicht klar ist, wie man Dir beibringt, erstmal ein gutes C++-Buch (vielleicht nicht Wolf, P&P, M+T, …Kompenium, …in 10 Tagen) ganz durchzulesen und ein klitzewenig C++ zu lernen, *bevor* Du ein Game proggers.
-
DLL und Dein Programm sind mit demselben Compiler und denselben Einstellungen erstellt?
Ansonsten ist es keine gute Idee Instanzen von Klassen als Parameter oder Rückgabewerte von Funktionen zu verwenden.
Nicht umsonst verwendet die WinApi nur structs unds Char-Zeiger.
-
Er reicht doch da nur Zeiger rum!?
-
volkard schrieb:
Aber nicht klar ist, wie man Dir beibringt, erstmal ein gutes C++-Buch (vielleicht nicht Wolf, P&P, M+T, …Kompenium, …in 10 Tagen) ganz durchzulesen und ein klitzewenig C++ zu lernen, *bevor* Du ein Game proggers.
Hättest du wenigstens den Post gelesen bevor du so überflüssige Kommentare abgibst wär dir nicht nur klar geworden das fGet() nicht so aussieht, und wir hätten uns dein MiMi erspaart.
Du bist wohl perfekt geboren worden hm?
Und wer sagt das es um ein bescheuertes Spiel geht.MichelRT schrieb:
DLL und Dein Programm sind mit demselben Compiler und denselben Einstellungen erstellt?
Ja. Beide MSVC2012 beide x64 eingestellt. Muss wirklich alles exakt gleich sein? Könnte Multibytezeichensatz soetwas auch beinflussen? also muss ich wirklich jede Projekteinstellung durchsehen?
MichelRT schrieb:
Ansonsten ist es keine gute Idee Instanzen von Klassen als Parameter oder Rückgabewerte von Funktionen zu verwenden.
Nicht umsonst verwendet die WinApi nur structs unds Char-Zeiger.Ok.. Jemand hatte mir erzählt es wäre durchaus gängig ganze Klassen aus Dlls zu holen. Gibt es denn andere Wege Klassen dynamisch in ein Programm zu kriegen? Also um ein Nachrüsten von Funktionen zu ermöglichen.
-
Belli schrieb:
Er reicht doch da nur Zeiger rum!?
Er reicht einen Zeiger auf ein Interface herum.
Mit dem Zeiger ruft er eine Methode auf -> Bumm.
Da liegt doch die Vermutung nahe, dass das aufrufende Progamm irgendwie das auf das der Zeiger zeigt falsch interpretiert
Deswegen meine Frage nach Compiler und Compilereinstellungen.
-
MichelRT schrieb:
Belli schrieb:
Er reicht doch da nur Zeiger rum!?
Er reicht einen Zeiger auf ein Interface herum.
Mit dem Zeiger ruft er eine Methode auf -> Bumm.
Da liegt doch die Vermutung nahe, dass das aufrufende Progamm irgendwie das auf das der Zeiger zeigt falsch interpretiert
Deswegen meine Frage nach Compiler und Compilereinstellungen.
Exakt. Aber ich habe keine Ahnung was ich dagegen tun kann...
Ich habe jetzt mal in den sourcecode der DLL reinDebugt. Der Pointer den ich z.b. an die Funktion bla(int* a) übergebe, wird völlig woanders auf den stack gelegt...
Auf der aufrufenden Seite hat der Zeiger eine ganz andere Adresse als in der DLL selbst.Muss ich mein _StrategyInterface im aufrufendem programm auch mit den Tags wie (__declspec(dllimport)) versehen?
Kann es vlt sein das die Funktionspointer die ich über "fGet = (DllClassGetFunction)(GetProcAddress(hDLL,"getClass"));" hole irgendwie quatsch sind?
Muss das Klassen Interface zu 100% Abstrakt sein? oder darf ich da wie jetzt auch vor definierte funktionen drin haben?
-
MichelRT schrieb:
Belli schrieb:
Er reicht doch da nur Zeiger rum!?
Er reicht einen Zeiger auf ein Interface herum.
Mit dem Zeiger ruft er eine Methode auf -> Bumm.
Da liegt doch die Vermutung nahe, dass das aufrufende Progamm irgendwie das auf das der Zeiger zeigt falsch interpretiert
Deswegen meine Frage nach Compiler und Compilereinstellungen.
Mein Zwischenruf bezog sich auf den Hinweis " keine gute Idee Instanzen von Klassen als Parameter oder Rückgabewerte von Funktionen zu verwenden."
-
Bei mir funktioniert's:
// DLL class StrategyInterface { public: virtual ~StrategyInterface(){} virtual string getStrategyName() = 0; virtual string getStrategyBrief() = 0; }; class Strategy : public StrategyInterface { public: string getStrategyName() { return "blubb"; } string getStrategyBrief() { return "bla"; } }; #define STRATEGYDLL_API __declspec(dllexport) BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID pReserved) { switch(dwReasonForCall) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } extern "C" STRATEGYDLL_API Strategy* getClass() { return new Strategy; }// exe class StrategyInterface { public: virtual ~StrategyInterface(){} virtual string getStrategyName() = 0; virtual string getStrategyBrief() = 0; }; typedef StrategyInterface*(__stdcall *getClass)(void); int main() { HMODULE hDLL; getClass fGet; StrategyInterface *cClass; hDLL = LoadLibraryA("VTableTest.dll"); // Funktioniert, hDLL ist nicht null. if(hDLL == NULL) { MessageBoxA(NULL, "Can't load library!", "Error", NULL); } fGet = (getClass)(GetProcAddress(hDLL,"getClass")); // Funktion wird auch gefunden. if(fGet == NULL) { MessageBoxA(NULL, "Can't get process address!", "Error", NULL); } else { StrategyInterface* bla = fGet(); std::cout << bla->getStrategyName() << std::endl; // hier gibt es einen Fehler. } system("pause"); }
-
okay... vielen Dank dafür das du es mal getestet hast!
Du hast zwar nur die vereinfachte Version getestet aber vom Ding her müsste es also funktionieren.
Ich werd das gleich mal auch in der vereinfachten Version testen und dann schauen wo da bei mir der wurm drin ist.
-
Belli schrieb:
MichelRT schrieb:
Belli schrieb:
Er reicht doch da nur Zeiger rum!?
Er reicht einen Zeiger auf ein Interface herum.
Mit dem Zeiger ruft er eine Methode auf -> Bumm.
Da liegt doch die Vermutung nahe, dass das aufrufende Progamm irgendwie das auf das der Zeiger zeigt falsch interpretiert
Deswegen meine Frage nach Compiler und Compilereinstellungen.
Mein Zwischenruf bezog sich auf den Hinweis " keine gute Idee Instanzen von Klassen als Parameter oder Rückgabewerte von Funktionen zu verwenden."
Und mein Einwurf bezog sich auf Methoden und funktionen einer DLL.
Klar darf man sonst Objekte als Parameter oder Rückgabewerte verwenden.
-
Lass mal den
typedef DllClassGetFunctionsehen.
Wenn da nicht so wie im vereinfachten Beispiel von asdfghjklöäqwert der stdcall steht dann ist es logisch dass Du Müll auf dem Stack siehst.
-
Ja, aber er reicht ja keine Instanzen (Objekte) herum, sondern lediglich Zeiger auf solche. Und das sollte meiner Meinung nach auch zwischen Client einer DLL und DLL keine Probleme bereiten.
-
Belli schrieb:
Ja, aber er reicht ja keine Instanzen (Objekte) herum, sondern lediglich Zeiger auf solche. Und das sollte meiner Meinung nach auch zwischen Client einer DLL und DLL keine Probleme bereiten.
Naja, wenn Compiler A den vtable einer Klasse vor das Objekt packt und Compiler B ans Ende und dann in B eine DLL aus A geladen wird und versucht eine virtuelle Funktion aufzurufen....
-
Sollte die V-Table nicht immer am selben Ort sein? Steht doch bestimmt in der Spezifikation, sonst hätte man das Problem unnötiger weiße bei anderen Versuchen Libs einzubinden ja auch.
-
Mr.Long schrieb:
Sollte die V-Table nicht immer am selben Ort sein? Steht doch bestimmt in der Spezifikation, sonst hätte man das Problem unnötiger weiße bei anderen Versuchen Libs einzubinden ja auch.
Soweit ich weis hat C++ keine einheitliche ABI, Microsoft hat allerdings durch COM einen quasi - Standard etabliert (also nicht für die komplette ABI sondern nur für die v-Table).
floorball
-
Unter was ordnet man dann __stdcall, __fastcall usw. ein?
-
calling conventions, stammt aus C
-
Nathan schrieb:
Belli schrieb:
Ja, aber er reicht ja keine Instanzen (Objekte) herum, sondern lediglich Zeiger auf solche. Und das sollte meiner Meinung nach auch zwischen Client einer DLL und DLL keine Probleme bereiten.
Naja, wenn Compiler A den vtable einer Klasse vor das Objekt packt und Compiler B ans Ende und dann in B eine DLL aus A geladen wird und versucht eine virtuelle Funktion aufzurufen....
Ist das denn wirklich so schwer zu verstehen?
MichelRT schrieb:
Ansonsten ist es keine gute Idee Instanzen von Klassen als Parameter oder Rückgabewerte von Funktionen zu verwenden.
Belli schrieb:
Ja, aber er reicht ja keine Instanzen (Objekte) herum, sondern lediglich Zeiger auf solche.
Was ist daran auszusetzen?
-
Belli schrieb:
Nathan schrieb:
Belli schrieb:
Ja, aber er reicht ja keine Instanzen (Objekte) herum, sondern lediglich Zeiger auf solche. Und das sollte meiner Meinung nach auch zwischen Client einer DLL und DLL keine Probleme bereiten.
Naja, wenn Compiler A den vtable einer Klasse vor das Objekt packt und Compiler B ans Ende und dann in B eine DLL aus A geladen wird und versucht eine virtuelle Funktion aufzurufen....
Ist das denn wirklich so schwer zu verstehen?
Genau dasselbe Problem ist auch mit Pointern...
-
Der sieht tatsächlich genauso aus wie der von ihm.
typedef StrategyInterface*(__stdcall *getClass)(void);