2009-07-29 9 views
1

Ich erstelle eine C++ Win32-DLL mit einigen globalen Daten. Es gibt eine std :: map, die global definiert ist, und es gibt exportierte Funktionen in der dll, die Daten in die Map schreiben (natürlich nach dem Erhalt einer Schreibsperre).Zugriff auf globale Daten in einer DLL von einer exportierten DLL-Funktion

Mein Problem ist, wenn ich die Write-Funktion aus der DLL DllMain aufrufen, funktioniert es ohne Probleme. Aber wenn ich die DLL-Datei von einem anderen Programm laden und die Funktion aufrufen, die Daten in die globale Karte schreibt, es gibt mir diese Fehlermeldung:

WindowsError: exception: access violation reading 0x00000008 

Gibt es etwas, das über das getan werden kann? Die gleiche Funktion, wenn sie von DllMain aufgerufen wird, hat Zugriff auf die globalen Daten in der DLL, aber wenn sie von einem anderen Prozess aufgerufen wird, hat sie keinen Zugriff auf die globalen Daten. Bitte um Rat.

Ich verwende den TDM-MinGW gcc 4.4.0 Compiler.

EDIT: Ok, ich habe herausgefunden, was das Problem ist, und vielen Dank für die Hilfe Jungs, aber das Problem war nicht mit einem Konstruktor Problem oder Unfähigkeit Karten im globalen Raum zu haben, aber ein Problem in das boost :: python, das ich benutze. Ich habe es getestet, aber da ich die DLL aus Python oder vielleicht etwas aufgerufen habe, wurde das Modul Urllib2 nicht in die DLL geladen. Jetzt muss ich sehen, wie ich es beheben kann.

+0

Es könnte eine gute Idee sein, Ihre Auflösung als Antwort aufzuschreiben und zu akzeptieren, damit die Frage als "beantwortet" dokumentiert wird. Entweder das oder eine vorhandene Antwort akzeptieren, die am hilfreichsten war. – RBerteig

Antwort

1

Sieht aus wie der Konstruktor von std::map nicht ausgeführt wurde, als Ihr Code aufgerufen wurde. Die Lebensdauer von globalen Nicht-PODs in einer Win32-DLL ist ziemlich schwierig, und ich bin nicht sicher, wie MinGW es speziell behandelt. Aber es kann sein, dass die Art, wie Sie die DLL kompilieren, Sie Ihre eigene Funktion (DllMain?) Als Einstiegspunkt festgelegt haben und somit die CRT-Initialisierungsroutine, die Konstruktoren aufruft, überschreiben.

+0

Ich habe irgendwo gelesen, dass alle globalen Objekte in einer DLL initialisiert werden, bevor DllMain (DLL_PROCESS_ATTACH) aufgerufen wird. Und ihre Destruktoren werden aufgerufen, nachdem DllMain (DLL_PROCESS_DETACH) aufgerufen wurde. Also nahm ich an, dass es funktionieren würde und schrieb zu viel Code. Aber wenn das nicht funktioniert, wäre es sicher, einen globalen Zeiger zu erstellen und die Karte in DllMain zu erstellen und zu zerstören? – Sahas

+0

Ich bin ziemlich sicher, dass der Konstruktor der std :: map aufgerufen wird, weil ich Daten in die Map in DllMain einfüge, wenn die Dll geladen wird, aber sobald sie geladen ist, wenn ich die Funktion von einem anderen Prozess aus aufrufen, es funktioniert nicht. – Sahas

+0

Was meinen Sie mit "Anruffunktion von einem anderen Prozess"? Eine DLL wird immer in den Prozess geladen, in dem sie verwendet wird. –

0

Sie müssen Shared Memory verwenden, da die verschiedenen Prozesse separate Adressräume haben. Ich denke, Sie werden nicht std :: map laufen lassen. Ich würde empfehlen, MapViewOfFile, CreateFileMapping, OpenFileMapping, ... und einfache alte Daten zu verwenden. Fragen Sie Google/MSDN.

+0

Die Daten, die ich erwähne, werden nur von der DLL benötigt, die ich erstelle, und die Anwendung, die die DLL verwendet, benötigt keinen Zugriff auf die Daten. Gibt es eine andere Möglichkeit, die Funktion auf die Daten zugreifen zu lassen? – Sahas

+0

Vielleicht können Sie einen der Prozesse als Besitzer der Daten definieren? Und: Sind die Schlüssel und Werte serialisierbar?Dann könnten Sie einige Mittel der Interprozesskommunikation verwenden. Dies ist in Ordnung, wenn die anderen Prozesse die Karte nicht zu sehr nutzen. –

1

Ein Lesefehler bei einer so niedrigen Speicheradresse bedeutet normalerweise, dass Sie versuchen, irgendwo auf einen NULL-Zeiger zuzugreifen. Können Sie Ihren tatsächlichen Code zeigen?

Verwandte Themen