Ver Mensaje Individual
  #21  
Antiguo 08-02-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por gushynet Ver Mensaje
a lo largo de las versiones, delphi ha sufrido muchas modificaciones en las RTTI y el funcionamiento de la VTM, de forma que es complejo desde el punto de vista de la compatibilidad tener un codigo RTTI que sirva para distintas versiones de delphi?, la pregunta viene de que estoy haciendo algo generico pero que me sirva para cualquier version de delphi, pero si la situacion es (no lo se) que para cada version de delphi han salido modificaciones en las RTTI y VMT de forma que hace imposible la compatibilidad usando RTTI...
Al menos en Win32, la mayoría de esas modificaciones han sido meras ampliaciones que conservan compatibilidad hacia atrás. Además por eso mismo introdujeron el operador VMTOffset que utilizo en el ejemplo y marcaron en desuso a varias constantes vmtXXX:
Código Delphi [-]
  ...
  vmtSafeCallException = -32 deprecated;  // don't use these constants.
  vmtAfterConstruction = -28 deprecated;  // use VMTOFFSET in asm code instead
  vmtBeforeDestruction = -24 deprecated;
  vmtDispatch          = -20 deprecated;
  vmtDefaultHandler    = -16 deprecated;
  vmtNewInstance       = -12 deprecated;
  vmtFreeInstance      = -8 deprecated;
  vmtDestroy           = -4 deprecated;

  vmtQueryInterface    = 0 deprecated;
  vmtAddRef            = 4 deprecated;
  vmtRelease           = 8 deprecated;
  vmtCreateObject      = 12 deprecated;

Cita:
Empezado por tema "Assembly directives" de la ayuda
VMTOFFSET retrieves the offset in bytes of the virtual method pointer table entry of the virtual method argument from the beginning of the virtual method table (VMT). This directive needs a fully specified class name with a method name as a parameter (for example, TExample.VirtualMethod), or an interface name and an interface method name.
Mientras emplees VMTOffset y este operador exista, no habrá problema alguno. Pero para versiones antiguas que no tuvieran el operador (no tengo el dato de desde qué versión fue introducido), habría que usar un código algo distinto.

Sin embargo la consulta en la VMT sólo resulta necesaria cuando el método base es abstracto (podría no serlo, implementándolo con sólo Begin y End). Como habrás visto, la otra función que escribí, RedefineProc1, "no" consulta a la VMT (en realidad sí lo hace, como siempre que hacemos referencia o llamamos a un método virtual, pero en este caso es responsabilidad implícita del compilador).

Incluso se me ocurre una tercera forma de hacer la comparación de punteros, que sirva con métodos abstractos y que no use el operador VMTOffset ni ninguna otra referencia explícita a la VMT. No es muy elegante, pero considero que podría ser práctica: consiste en crear una instancia "dummy" de la clase base que declara el método abstracto, para poder hacer una comparación tipo Metodo.Code <> MetodoInstanciaDummy.Code (adaptando la función RedefineProc1 que escribí antes).

Gracias por anexar el código, gushynet. Le echaré un vistazo en estos días.

Saludos.

Al González.

Última edición por Al González fecha: 08-02-2009 a las 20:55:30.
Responder Con Cita