Artikel-ID: 172396 - Geändert am: Freitag, 2. September 2005 - Version: 3.0

Wenn Sie ein STL-Objekt über einen Zeiger oder Verweis in einer anderen DLL oder EXE-Datei zugreifen können eine Zugriffsverletzung auftreten

SystemtippDieser Artikel bezieht sich auf ein anderes Betriebssystem als das von Ihnen verwendete. Für Sie möglicherweise nicht relevante Artikelinhalte wurden deaktiviert.

Auf dieser Seite

Alles erweitern | Alles schließen

Problembeschreibung

Beim Zugriff auf eine STL-Objekt in einer DLL oder EXE-Datei über einen Zeiger oder Verweis in eine andere DLL oder EXE erstellt, können eine Zugriffsverletzung oder andere schwerwiegende Programmfehler, die die Darstellung des Datenbeschädigung oder-Verlust einschließlich auftreten.

Ursache

Die meisten Klassen in C++-Standardbibliotheken verwenden statische Datenmember, direkt oder indirekt. Da diese Klassen durch Vorlage Instanziierung generiert werden, wird jede ausführbares Abbild (normalerweise mit DLL- oder EXE-Dateinamenerweiterungen) seine eigene Kopie der statischen Datenelements für eine bestimmte Klasse enthalten. Wenn eine Methode der Klasse, die den statischen Datenmember erfordert ausgeführt wird, verwendet er statischer Datenmember im ausführbaren Bild in dem Methodencode befindet. Da die statische Datenmember in ausführbare Abbilder nicht synchron sind, diese Aktion konnte eine Zugriffsverletzung führt, oder Daten scheinbar verloren geht oder beschädigt werden.

Lösung

  1. Exportieren von Accessormethoden aus ausführbares Abbild, das die STL erstellt Objekt. Diese Methoden umschließen die erforderliche Funktionalität des STL-Objekts. Auf diese Weise wird das STL-Objekt nur direkt in ein einzelnes ausführbares Abbild zugegriffen werden. Genommen Sie an, MyProgram.EXE benötigt, um das nächste Element in Deque <myclass> zu erhalten, die sich in MyLibrary.DLL befindet. MyLibrary.DLL konnte eine Accessormethode MyClass 1 DequeNextItem exportieren (/ *... * /). MyProgram.EXE konnte dann diese Methode zum Abrufen des nächsten Elements in der Deque ausgeführt. Finden Sie im Codebeispiel unten ein vollständigeres Beispiel.

    Diese Option kann für STL-Objekte, die entweder globale, statische oder statischer Datenmember einer Klasse sind, die nicht aus einer DLL exportiert werden. Diese Option funktioniert nicht für nicht-statisches Datenmember einer Klasse, die aus einer DLL exportiert werden, oder für automatische Daten.
  2. Exportieren der Instanziierung des Vorlage-Klasse aus ein ausführbares Abbild, und andere ausführbare Bilder importieren. Beispielsweise wenn MyLibrary.DLL einen Zeiger zu Vektor < MyClass > zurück an eine Funktion in MyProgram.EXE übergibt, anschließend exportieren Sie die Klassen MyClass und Vektor < MyClass > von MyLibrary.DLL. Importieren Sie diese Klassen werden dann in MyProgram.EXE. Auf diese Weise müssen Sie eine Kopie der statische Klassenmember in MyLibrary.DLL. Weitere Informationen zum Exportieren und Importieren von STL finden Sie im folgenden Artikel der Microsoft Knowledge Base:
    168958  (http://support.microsoft.com/kb/168958/ ) Zum Exportieren von STL-Komponenten innerhalb und außerhalb einer Klasse

Status

Es handelt sich hierbei um ein beabsichtigtes Verhalten.

Weitere Informationen

Schritte zum Reproduzieren des Verhaltens

   //---------------------------------------------------------
   // AVEXE.CPP
   // Compile options needed: /GX
   #pragma warning (disable : 4786)
   #include <map>
   #include <string>
   #include <stdio.h>

   __declspec(dllimport)
   std::map<int,std::string>* GiveMeAMap(int n);

   __declspec(dllimport)
   void ShowMeTheMap(std::map<int,std::string> *amap);

   __declspec(dllexport)
   const char* MapItemX (std::map<int,std::string> *m, int x);

   int main () {

      // Create the map in the DLL
      int x = 6;
      std::map<int,std::string> *p = GiveMeAMap(x);

      // Display the contents of the map from the DLL
      printf("Showing contents from the DLL\n");
      ShowMeTheMap(p);

      // Display the contents of the map from the EXE
      // using the accessor function from the DLL so we
      // aren't directly accessing the map
      printf("Showing contents from the EXE using accessor\n");
      int i = x;
      while (i--) {
         printf("%d = %s\n",i,MapItemX(p,i));
      }

      // Access Violation when accessing the map that
      // was created in the DLL from the EXE
      printf("Showing contents from the EXE directly\n");
      while (x--) {
         printf("%d = %s\n",x,(*p)[x].c_str());
      }

      return 0;
   }

   //---------------------------------------------------------
   // AVDLL.CPP
   // Compile options needed /GX
   #pragma warning (disable : 4786)
   #include <map>
   #include <string>
   #include <stdlib.h>

   // Create the map here in the DLL
   __declspec(dllexport)
   std::map<int,std::string>* GiveMeAMap(int n) {
      std::map<int,std::string> *m = new std::map<int,std::string>;
      while(n--) {
         char b[33];
         itoa(n,b,2);
         (*m)[n] = std::string(b);
      }
      return m;
   }

   // We can access the map without error from the executable
   // image where the map was created
   __declspec(dllexport)
   void ShowMeTheMap(std::map<int,std::string> *p) {
      int x = p->size();
      while (x--) {
         printf("%d = %s\n",x,(*p)[x].c_str());
      }
   }

   // An accessor method to return the associated C string
   // for key x
   __declspec(dllexport)
   const char* MapItemX (std::map<int,std::string> *m, int x) {
      return (*m)[x].c_str();
   }
				

Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
Keywords: 
kbmt kbtshoot kbcrt kbprb KB172396 KbMtde
Maschinell übersetzter ArtikelMaschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 172396  (http://support.microsoft.com/kb/172396/en-us/ )
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.