DLL crasht VB6-Anwendung
-
Guten Morgen.
Folgendes Problem:
Eine DLL, geschrieben in C++ und mit Abhängigkeiten nur zur CRT und WinAPI-DLLs, wird in einem VB6-Projekt verwendet. Diese Anwendung kann in der VB6-Entwicklungsumgebung nur 1x gestartet werden, beim 2. Start stürzt die komplette IDE mit der Fehlermeldung "unknown software exception" ab. Der Disassembler/Debugger von VB6 sagt mir dann, dass es ein Problem der DLL ist. Allerdings bin ich mir sicher, dass es keine Exceptions in meinem Code gibt, die nicht auch dort verarbeitet werden.Wie kann ich den Code meiner DLL mit dem Debugger verknüpfen, damit ich nicht auf den wenig aussagekräftigen Disassembler von VB6 angewiesen bin?
Kennt jemand vielleicht übliche Fehlerquellen für ein solches Verhalten?
Noch zur Info: VB6 muss laut Vorgabe verwendet werden, Alternativen gibt es nicht. Die DLL wird mit VS2005 entwickelt.
Grüße
Martin
-
ist die dll statisch oder dynamisch gelinkt zur VB6 App?
-
Die exportierten Funktionen der DLL werden in VB mittels
Private Declare Sub EineFunktion Lib "Meine.dll" (ByVal EinParameter As Long) As EinRückgabewert
eingebunden. Meine Erfahrungen mit VB sind rudimentär, allerdings gehe ich davon aus, dass es in diesem Fall dynamisch geschieht.
-
Was ist den "EinRückgabewert"?
-
d.h. wenn du zwei Instanzen deiner VB6 Anwendung startest, crashed deine DLL... könnte es sein das es Probleme gibt, wenn mehre Instanzen deine Dll ressourcen verwenden?
zur not: Debug log Datei verwenden..
-
Was ist den "EinRückgabewert"?
evtl. ne struktur^^
-
Jochen Kalmbach schrieb:
Was ist den "EinRückgabewert"?
Primitive wie Boolean oder Long, nichts wilderes, aus Gründen der Robustheit.
Jihhaaaa schrieb:
d.h. wenn du zwei Instanzen deiner VB6 Anwendung startest, crashed deine DLL... könnte es sein das es Probleme gibt, wenn mehre Instanzen deine Dll ressourcen verwenden?
zur not: Debug log Datei verwenden..
Nein, nicht, wenn ich 2 Instanzen verwende. Die DLL kann problemlos von mehreren Instanzen (getestet: >10) der VB6-Anwendung verwendet werden, daran wird es nicht liegen. Der Fehler tritt auf, wenn ich die Anwendung innerhalb der IDE mittels F5 starte. Beim 1. Start ist es kein Problem, beim 2. crashts.
Außerhalb der IDE funktionierts prima. Da es allerdings laut Debugger innerhalb der DLL crasht, wenn ich die IDE nutze, möchte ich wissen, woran das liegt, damit mir die DLL nachher im Produktiveinsatz nicht abschmiert.
Was genau meinst du mit Debug Log File?
-
die VB6 IDE hat ihre tücken...:)
-
Dann debug halt die DLL!?
DLL-Projekt mit VS2005 öffnen Breakpoint setzen und als Program "vb6.exe" angeben. F5!
-
aber dann startet er ja die VB exe nicht in der VB6 IDE , sondern als fertige exe dass will er ja nicht...
-
BorisDieKlinge schrieb:
aber dann startet er ja die VB exe nicht in der VB6 IDE , sondern als fertige exe dass will er ja nicht...
Hä??? Er will doch die VB-IDE starten und dort das VB-Projekt, oder?
Und da in VB6 das VB-Projekt in der IDE läuft ist dies genau das was er tun muss...
-
Nene, Jochen Kalmbach hat schon recht so. Mir war diese "Attach to process"-Geschichte noch so nicht bekannt, aber es funktioniert und ich weiß jetzt auch, wo es knallt.
CreateWindowEx ist der Punkt, wo es beim 2. Durchlauf crasht. Es wird eine unbehandelte Ausnahme in der Datei iosfwd in der Funktion _Copy_s(...) geworfen. Hat jemand eine Idee, woran das liegen könnte? Hab auch schon versucht, in der WndProc der Fensterklasse zu schauen, aber bis dort kommt es gar nicht erst.
grüße
Martin
-
Ok, Update:
CreateWindowEx crasht, weil die Fensterklassen nicht registriert sind. Beim Starten der DLL werden 2 Fensterklassen für 2 Fenster erzeugt und registriert. Im 1. Durchlauf funktioniert das, im 2. nicht mehr. Am Ende des ersten Durchlaufs werden die erzeugten Klassen wieder mit UnregisterClass(..) weggeräumt. Allerdings können die Klassen danach nicht mehr neu erzeugt werden. GetLastError() liefert mir ERROR_CLASS_ALREADY_EXISTS, obwohl ich vorher UnregisterClass aufgerufen habe...
Ideen?
-
Das Problem ist vermutlich, dass VB6 diese DLL nur beim *ersten Starten* in den Adressraum lädt!
Die DLL bleibt dann immer in diesem Adressraum drin! Beim zweiten Start ist die DLL *immer noch* geladen! Somit darfst Du die Fenster-Klassen nicht nochmals registrieren, da sie ja noch immer registriert sind (die DLL wurde ja nicht entladen!).
-
Ok, das war es. Ich werde jetzt meine Fensterklassen an der Stelle DllMain:DLL_PROCESS_ATTACH registrieren. So läufts und gibt auch keine Fehler.
Was mich dennoch wundert: Ist der Befehl RegisterClass irgendwie destruktiv? Normalerweise würde ich davon ausgehen, dass bei einem Error 1410 (class exists) nichts passieren dürfte, aber dennoch crasht das CreateWindowEx, wenn es die Klasse sucht.
Naja, das Verhalten von Windows ist manchmal nicht leicht zu durchschauen...
Danke für die Tips und Grüße
Martin
-
In DllMain würde ich sowas nicht machen (siehe Doku zu DllMain).
Merkr Dir doch einfach in einer globalen Variable, ob Du das Regsiter-Class schon ausgeführt hast oder nicht...