Artigo: 172396 - Última revisão: sexta-feira, 2 de Setembro de 2005 - Revisão: 3.0

Poderá detectar uma violação de acesso quando acede a um objecto STL através um ponteiro ou uma referência numa EXE ou DLL diferente

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 | Reduzir tudo

Sintomas

Ao aceder a um objecto STL criado de uma DLL ou EXE através de um ponteiro ou uma referência numa EXE ou DLL diferente, poderá detectar uma violação de acesso ou outros erros de programa graves incluindo o aspecto de danos nos dados ou perda de dados.

Causa

A maior parte das classes no padrão bibliotecas de C++ utilizar membros de dados estáticos ou indirectamente. Uma vez que estas classes são geradas através da instância de modelo, cada imagem executável (geralmente com extensões de nome de ficheiro DLL ou EXE) irá conter a sua própria cópia do membro dados estáticos para uma determinada classe. Quando é executado um método de classe que requer o membro de dados estáticos, utiliza o membro de dados estáticos na imagem executável em que reside o código do método. Uma vez que os membros de dados estáticos em imagens executáveis não são sincronizados, esta acção pode resultar numa violação de acesso ou dados poderão ter perdido ou danificado.

Resolução

  1. Origem métodos do descritor de acesso a imagem executável que criou o STL objecto. Estes métodos moldar a funcionalidade necessária do objecto STL. Desta forma, o objecto STL vai apenas ser directamente acedido dentro de uma única imagem executável. Por exemplo, suponha que MyProgram.EXE necessita de obter o elemento seguinte na deque <myclass> que reside numa MyLibrary.DLL. MyLibrary.DLL pode exportar um método de descritor de acesso, MyClass * DequeNextItem (/ *... * /). Em seguida, MyProgram.EXE poderia executar este método para obter o item seguinte no deque. Consulte o exemplo de código abaixo um exemplo mais completo.

    Esta opção funciona para objectos STL são ambos membros de dados estáticos, global ou estáticos de uma classe que não são exportados a partir de uma DLL. Esta opção não irá funcionar para membros de dados não estático de uma classe que são exportados a partir de uma DLL ou dados automático.
  2. Exportar a instância da classe de modelo a partir de uma imagem executável e importá-lo para outras imagens executáveis. Por exemplo, se MyLibrary.DLL passar um apontador para vector < MyClass > novamente para uma função em MyProgram.EXE, em seguida, exportar as classes MyClass e vector < MyClass > do MyLibrary.DLL. Em seguida, importe estas classes para MyProgram.EXE. Ao fazê-lo, terá uma cópia dos membros da classe estática que resida na MyLibrary.DLL. Para obter mais informações sobre como exportar e importar STL, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
    168958  (http://support.microsoft.com/kb/168958/ ) Como exportar STL componentes dentro e fora de uma classe

Ponto Da Situação

Este comportamento ocorre por predefinição.

Mais Informação

Passos 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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/ )