Error: Recibe un "0xc0000005" código de error cuando se desencadena un evento nativo o se desenlazaría

Seleccione idioma Seleccione idioma
Id. de artículo: 811193 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Síntomas

Cuando se desencadena el evento __raise o desenlazar los eventos nativos ( __unhook ), en una aplicación no administrada, puede recibir el siguiente mensaje de error:
Excepción en la virtual address en executable no controlada: 0xc0000005: infracción de acceso lectura ubicación virtual address
donde virtual address y executable son valores que son específicos de la aplicación.

Causa

El problema se produce cuando se definió el constructor del origen de eventos fuera del ámbito de clase. No se ha inicializado la lista de controlador de eventos en el constructor del origen de eventos en el código insertado. Por lo tanto, la infracción de acceso se produce cuando se tiene acceso a la memoria sin inicializar.

Solución

Para evitar este problema, utilice uno de los métodos siguientes:

Método 1

Definir el constructor del origen de eventos en su ámbito de clase. Para ello, reemplace el código existente: estructura
struct A {
	__event void Event(); 
	A(); 
	void bar(){} 
};
//Constructor defined outside class scope.
A::A() { } 
con el siguiente código: estructura
struct A {
	__event void Event(); 
	A() { }; //Contructor defined in class scope.
	void bar(){} 
};

Método 2

Incluir el código de inicialización eventHandlerList en el constructor de origen de evento. Esto supone que el archivo .cpp que contiene la definición de clase de origen de evento es event.cpp. El código insertado que se genera el compilador puede almacenarse en un archivo intermedio con Ayuda de la opción del compilador de línea de comandos de /fx .
  1. En el símbolo del sistema, escriba el siguiente comando:
    cl /Fx event.cpp
    el código insertado que generados por el compilador se guarda en un archivo con el. mrg.cpp extensión. Para event.cpp, el archivo con el código insertado es event.mrg.cpp.
  2. En el archivo intermedio que generado (event.mrg.cpp), agregue el código siguiente al constructor de origen de evento:
    • Si se define la clase de origen de evento que se llama A en un espacio de nombres X , agregue el código siguiente:
      __eventHandlerList_X_A_Event = 0;
      al constructor de .
    • Si la clase de origen de evento que se denomina A no está definida en cualquier espacio de nombres, agregue el código siguiente:
      __eventHandlerList_A_Event = 0;
      al constructor de .
    Donde A es la clase de origen de evento, X es el espacio de nombres A y eventos es que el evento identificado por la palabra clave __event en el evento clase de origen.
  3. Compile el archivo intermedio en el símbolo del sistema con el siguiente comando:
    cl event.mrg.cpp

Estado

Microsoft ha confirmado que se trata de un problema de los productos de Microsoft enumerados al principio de este artículo.

Más información

Pasos para reproducir el comportamiento


Puede reproducir el problema con cualquiera de los dos escenarios siguientes:

Escenario 1

Definir un origen de eventos dentro de un espacio de nombres. Además, el origen de evento y el receptor de eventos se implementan mediante la misma clase o estructura. Para ello, siga estos pasos:
  1. En Visual Studio. NET, cree una consola de Win32 C++ Visual proyecto de aplicación.
  2. En el cpp archivo predeterminado que se genera para la aplicación, reemplace el código existente con el siguiente código:
    #include "stdafx.h"
    namespace X 
    { 
    //Both event source and event receiver
    	struct A {
    	 	__event void Event(); 
    		A(); 
    		void bar(){} 
    	};
    }
     
    X::A::A() { } 
    
    int main()
    { 
    	X::A a; 
    	__hook(&X::A::Event, &a, &X::A::bar, &a); 
    	a.Event(); 
    	__unhook(&X::A::Event, &a, &X::A::bar, &a); 
    } 
  3. Genere y ejecute la aplicación.
Recibirá el mensaje de error descrita en la sección "Síntomas" de este artículo.

Escenario 2

Definir un origen de evento y receptor de eventos en dos diferentes clases o estructuras. Para ello, siga estos pasos:
  1. En Visual Studio. NET, cree una consola de Win32 C++ Visual proyecto de aplicación.
  2. En el cpp archivo predeterminado que se genera para la aplicación, reemplace el código existente con el siguiente código:
    #include "stdafx.h"
    //Event source
    struct A {
    	__event void Event();
    	A();
    };
     
    //Event Receiver
    struct B
    {
    	void bar();
    };
    
    void B::bar(){} 
    A::A() { } 
    
    int main()
    {
    	A a;
    	B b;
    	__hook(&A::Event, &a, &B::bar, &b);
    	a.Event();
    	__unhook(&A::Event, &a, &B::bar, &b); 
    }
  3. Genere y ejecute la aplicación.
Recibirá el mensaje de error descrita en la sección "Síntomas" de este artículo.

El problema se produce porque el compilador genera código incorrecto insertado para el constructor del origen de eventos. Para ver el código insertado generado por el compilador, compile el código anterior en el símbolo del sistema como sigue:
cl /Fx event.cpp
donde el código se guarda en event.cpp. El código generado por el compilador está disponible en un archivo que se denomina event.mrg.cpp. El constructor de clase de evento no contiene el código de inicialización eventHandlerList siguiente cuando el constructor de clase de evento está definido fuera del ámbito de clase:
  • Cuando la clase de origen de evento que se denomina A está definida en un espacio de nombres X
    __eventHandlerList_X_A_Event = 0;
  • Cuando la clase de origen de evento que se denomina A no se define en cualquier espacio de nombres
    __eventHandlerList_A_Event = 0;
Donde A es la clase de origen de eventos, X es el espacio de nombres A y eventos es el evento que se identifica mediante la palabra clave __event en el evento de origen de clase.

Nota Similarmente, la palabra clave __raise event presenta el mismo comportamiento que se muestra la palabra clave evento __unhook .

Referencias

Para información adicional acerca de cómo controlar las palabras clave y atributos de evento nativo, consulte el siguiente sitio Web de MSDN:
Palabras clave de control de eventos
http://msdn2.microsoft.com/en-us/library/6f01ek09(vs.71).aspx

Propiedades

Id. de artículo: 811193 - Última revisión: martes, 13 de noviembre de 2007 - Versión: 1.3
La información de este artículo se refiere a:
  • Microsoft Visual C++ .NET 2002 Standard
Palabras clave: 
kbmt kbcompiler kberrmsg kbbug KB811193 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 811193

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com