2009-07-03 13 views
8

Estoy tratando de implementar el manejo de excepciones para un sistema operativo incorporado y estoy atascado en cómo detectar el tipo de la "excepción" arrojada (para seleccionar el controlador apropiado).¿Cuál es la implementación más simple de RTTI para C++?

Las partes que guardan y restauran el contexto del manejo de excepciones ya están hechas, pero no puedo tener identificadores específicos ya que no puedo detectar el tipo de 'excepción' arrojada. La implementación estándar de RTTI de C++ es demasiado dependiente de otras bibliotecas y por esa razón actualmente estoy considerando que no está disponible.

Considerando que mi objetivo es un sistema integrado y por esa razón no puedo crear mucho código, ¿cuál es la implementación más pequeña de "Información de tipo de tiempo de ejecución" que puedo obtener (o crear)?

- Editar -

no estoy trabajando en el compilador, es una IA32-g ++.

+1

¿Está escribiendo/modificando el compilador o el tiempo de ejecución del idioma, o dónde exactamente va a encajar esto? Un poco más de contexto sería bueno. – jalf

+0

Si tiene memoria limitada, no debe habilitar RTTI, o incluso tratar de usar excepciones.Mejor piense en un enfoque alternativo. –

+0

Si se ha lanzado una excepción, de ninguna manera ha codificado la información del tipo de excepción, por lo que no veo por qué necesita algún método "alternativo". Como dijo jalf, danos más información sobre lo que realmente estás tratando de hacer. –

Respuesta

11

Como está trabajando en un entorno incrustado, presumiblemente prefiere soluciones extremadamente mínimas y puede aprovechar hechos no estándar o no portátiles sobre su compilador.

Si una clase es polimórfica (tiene al menos una función virtual propia) en C++, probablemente tenga un puntero a un vtable incrustado en alguna parte de ella. Es posible que el puntero vtable aparezca al comienzo del diseño del objeto en la memoria.

Esto es cierto para muchos compiladores, los que utilizan el C++ ABI - a related SO question here.

Si es así, puede ser capaz de obtener en la viable como esto:

void *get_vtable(void *obj) 
{ 
    return *(reinterpret_cast<void **>(obj)); 
} 

A continuación, se puede comparar el vtables de dos punteros-a-objetos para ver si apuntan a un mismo tipo de objeto

lo tanto, un "interruptor de tipo" (que es lo que es, básicamente, de captura) haría algo como esto:

P p; 
Q q; 
if (get_vtable(caught) == get_vtable(&p)) 
{ 
    // it's a P... 
} 
else if (get_vtable(caught) == get_vtable(&q)) 
{ 
    // it's a Q... 
} 

Usted puede ocultar ese patrón en una macro de captura.

Punto importante - si se derive una clase de una base, pero la clase derivada no anula las funciones virtuales o añadir nuevas funciones virtuales, entonces el compilador podría reutilizar concebible vtable de la clase base para la clase derivada. Esto significa que para distinguir entre dos tipos de excepción, cada uno debe anular una función virtual para garantizar que tengan sus propios tablas virtuales.

Tenga en cuenta que esto es solo una pequeña fracción de lo que implica el manejo de excepciones. ¡También está la pequeña cuestión de desenrollar la pila! Debe llamar a los destructores de todos los objetos en la pila cuando salta al controlador. No es solo cuestión de hacer setjmp/longjmp.

+0

¿Puedes mostrar una forma de obtener el 'ptr' en el primer código? Y tampoco entendí el rol de 'obj'. – freitass

+0

Disculpa, eso fue un error tipográfico. Es solo un puntero a un objeto de tipo polimórfico. –

2

El RTTI más simple que puedo pensar es derivar todas las clases desde una base común que tenga una función virtual pura "GetType()". O consigue que devuelva una cadena o cree una enorme enumeración con todos los tipos. Es bastante simple, es rápido y tiene poca carga de memoria. No es particularmente flexible, sin embargo.

+0

Por supuesto, para que existan funciones virtuales, probablemente utilice algún tipo de tabla de puntero de función virtual. Que de alguna manera se podría hacer para ser utilizado para rtti ... – gimpf

+0

un poco más complicado que el método enum gigante;) – Goz

+0

Debe agregarse un poco menos de plataforma cruzada también ... encontrar esos VTables puede ser un trabajo sangriento. – Goz

Cuestiones relacionadas