2011-04-21 6 views
5

¿Es posible acceder a la tabla v de una función en tiempo de ejecución? ¿Se puede determinar la metainformación, como el número de diferentes versiones de funciones? Esta podría ser una pregunta más teórica, pero ¿podría un desarrollador poner un límite al número de clases que pueden extender una clase base dada al asegurarse de que la tabla v nunca exceda un cierto número de filas?Acceso a v-table en tiempo de ejecución

+0

Pregunta algo similar: http://stackoverflow.com/questions/5099967/how-to-obtain-a-pointer-out-of-ac-vtable – iammilind

+0

Bueno, usted * puede * acceder al vtable en tiempo de ejecución mediante ensamblaje (no portátil, obviamente) ... pero aún no puede hacer esas otras cosas que pidió (determinar o limitar el tamaño de vtable) –

Respuesta

12

¿Es posible acceder a la tabla v de una función en tiempo de ejecución? ¿Se puede determinar la metainformación, como el número de diferentes versiones de funciones?

No de forma portátil. La norma no tiene ni siquiera el concepto de tabla virtual, es más de un detalle de implementación que un requisito, incluso si todas las implementaciones que saben utilizar vtables. En el caso general no habrá incluso tener la información disponible en tiempo de ejecución (es decir, el compilador no necesita almacenar el número de entradas en la viable, ya que ve el tipo y puede contar)

Podría una el desarrollador pone un límite al número de clases que pueden extender una clase base determinada al asegurarse de que la tabla v nunca exceda un cierto número de filas?

De nuevo no, pero como esto muestra una idea errónea, podría valer la pena tratarla aparte.Cuando una clase base tiene cualquiera de las funciones virtuales, el compilador (en todas las implementaciones que usan tablas virtuales) creará el vtable y esa tabla tendrá exactamente 1 entrada por función virtual en la clase base (más algunos datos adicionales --typeinfo o puntero a it, offset al comienzo del objeto u otros detalles de implementación). Cuando una clase amplía esa clase base, no agregará nuevos elementos a ese vtable, sino que creará un vtable separado (o más, dependiendo de la jerarquía de tipos). Si la función derivada no agrega ninguna función virtual nueva, el vtable para el objeto derivado contendrá la cantidad exacta de elementos que tenía el vtable original. Es decir, puede tener una gran jerarquía de herencias sin que eso afecte en absoluto al diseño de vtable. ¿Qué va a cambiar son los datos almacenados y los typeinfo punteros a cada función virtual, que se referirá a la última overrider

+1

+1, especialmente para abordar la idea errónea sobre el tamaño y el diseño de vtable. –

3

¿Se puede determinar una metainformación como el número de diferentes versiones de funciones?

No C++ no es compatible con reflection. Lo que estamos tratando de lograr no es posible en C++ yo sepa

1

En teoría, sí, porque está almacenada en la memoria y que tienen acceso a ella. En la práctica, no existe una manera sensata y portátil de hacerlo, porque el compilador puede implementar funciones virtuales de la forma que quiera, por lo que tendría que buscar en el código fuente de su compilador cómo/dónde acceder a la información deseada. información y cómo interpretarlo.

0

Puede usar el Debug Interface Access SDK u otras interfaces de soporte de depuración (gdb) para este tipo de cosas.

RTT datos son más portátiles, pero pueden no tener suficientes detalles para su proyecto.

Para su pregunta específica sobre limitar la tabla v e impedir que se extienda demasiado, puede intentar this method;

IDiaSymbol :: get_classParente Recupera una referencia al padre de clase del símbolo.

HRESULT get_classParent (IDiaSymbol** pRetVal); 

Puede investigar todos los tipos de símbolos relacionados con la clase here, lo que es posible que desee hacer es enumerar todos los tipos de clase cargada, get_classParent de forma recursiva y mantener un recuento de todas las clases que se extienden a su base.

Su clase también podría requerir que los símbolos estén disponibles durante el inicio para ayudar a la aplicación.

+1

Un * puntero de tabla base virtual * no es un * puntero * a la * tabla virtual * de una base, pero más bien un * puntero * al * vtable * de una * base virtual *. Tenga en cuenta que 'virtual' va con la base, no con la tabla. Como tal, solo tiene sentido cuando tienes herencia virtual: 'struct derived: virtual base {};' –

+0

@David: +1 Esta respuesta tiene funciones virtuales y clases base virtuales mezcladas. –

+0

Estoy seguro de que tendrá que hacer mucho más que usar una sola llamada de todos modos, por lo que dije: "Son bastantes otras interfaces, puede que necesite usar otros métodos para obtener toda la información que necesita. " Creo que debería haber sido un poco más enfático sobre esa necesidad. : \ – RandomNickName42

0

El único rayo de esperanza que podía imaginar por su esfuerzo, es el manejo de moldeado dinámico. Cada compilador, con el correspondiente soporte de biblioteca, tiene algún concepto de atravesar una jerarquía para lograr un lanzamiento dinámico. Si pudieras conectarte con ese recorrido, entonces sabrías algo sobre cuántos niveles de herencia estás tratando. Dicho esto, incluso si hiciera esto funcionar, sería específico del compilador (como han dicho otros) ya que dicha implementación es de propiedad exclusiva.

Cuestiones relacionadas