ID do artigo: 172396 - Última revisão: sexta-feira, 2 de setembro de 2005 - Revisão: 3.0

Você pode perceber uma violação de acesso quando você acessa um objeto STL através de um ponteiro ou referência em uma DLL ou EXE diferentes

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo

Sintomas

Ao acessar um objeto STL criado em uma DLL ou EXE através de um ponteiro ou uma referência em uma DLL ou EXE diferentes, você pode enfrentar uma violação de acesso ou outros erros de programa grave incluindo a aparência de corrupção de dados ou perda de dados.

Causa

A maioria das classes nas bibliotecas C++ padrão use membros de dados estáticos ou indiretamente. Como essas classes são geradas via instanciação de modelo, cada imagem executável (geralmente com extensões de nome de arquivo DLL ou EXE) irá conter sua própria cópia do membro de dados estáticos para uma determinada classe. Quando um método da classe que requer o membro de dados estáticos é executado, ele usa o membro de dados estáticos na imagem executável no qual reside o código de método. Como os membros de dados estáticos em imagens executáveis não estiverem em sincronia, essa ação pode resultar em uma violação de acesso ou dados podem aparecer estar perdido ou corrompido.

Resolução

  1. Exportar métodos acessadores de imagem executável que criou a STL objeto. Esses métodos dispor a funcionalidade necessária do objeto STL. Dessa forma, o objeto STL será apenas ser acessado diretamente dentro de uma única imagem executável. Por exemplo, suponha que MyProgram.EXE precisa obter o próximo elemento no deque <myclass> que reside no MyLibrary.DLL. MyLibrary.DLL pode exportar um método do acessador, MyClass 1 DequeNextItem (/ *... * /). Em seguida, MyProgram.EXE pode executar esse método para obter o próximo item no deque. Consulte o código de exemplo abaixo um exemplo mais completo.

    Esta opção funciona para objetos STL que são membros de uma classe dados estáticos, estática ou global que não são exportados de uma DLL. Esta opção não funcionará para membros non-static dados de uma classe que são exportados de uma DLL ou de dados automáticos.
  2. Exportar a instanciação de classe de modelo de uma imagem executável e importá-lo para outras imagens executáveis. Por exemplo, se MyLibrary.DLL passa um ponteiro para o vetor < MyClass > de volta para uma função em MyProgram.EXE, em seguida, importar as classes MyClass e vetor < MyClass > de MyLibrary.DLL. Em seguida, importe essas classes para MyProgram.EXE. Fazendo isso, você terá uma cópia dos membros da classe estática que residem em MyLibrary.DLL. Para obter mais informações sobre como exportar e importar STL, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
    168958  (http://support.microsoft.com/kb/168958/ ) Como exportar os componentes STL dentro e fora de uma classe

Situação

Esse comportamento é por design.

Mais Informações

Etapas para reproduzir o comportamento

   //---------------------------------------------------------
   // 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();
   }
				

A informação contida neste artigo aplica-se a:
  • 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
Palavras-chave: 
kbmt kbtshoot kbcrt kbprb KB172396 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 172396  (http://support.microsoft.com/kb/172396/en-us/ )