Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-02-2009
gushynet gushynet is offline
Miembro
 
Registrado: ago 2008
Posts: 26
Poder: 0
gushynet Va por buen camino
Hola, pues gracias a las aportaciones de todos los que os habeis interesado por el tema ya se por donde van los tiros.

AL Gonzales (ahora si lo escribi bien ) no he probado el codigo, mas que nada porque prefiero primero entender bien como funciona el tema de la tabla virtual y realizar mi propio codigo ya que si no no se aprende . De todas formas si a alguien le interesa lo que estoy haciendo no tiene nada mas que pedirme el codigo. Probablemente tendra algunos errores (poco optimizado o nada) pero creo que es una buena manera de conocer un poco las RTTI, asi que si alguien lo quiere....


Otra duda: el uso de las RTTI merman el rendimiento de una aplicación? la duda viene de que las funciones RTTI entiendo que tienen que navegar por la jerarquia de clases y eso debe ser desde un punto de vista computacional muy costoso? estoy en lo cierto?

Y otra pregunta mas: con las RTTI he conseguido informacion sólo sobre propiades de la seccion published. Se puede ir mas lejos y poder conseguir en tiempo de ejecucion informacion sobre propiedades que esten en las otras secciones?

e informacion sobre variables?

por lo que he visto solo se permite para propiedades (y no variables) que esten declaradas en published, pero teniendo en cuenta la falta de documentacion sobre las RTTI a lo mejor si es posible obtener informacion de cualquier componente, sea simple o no, de un objeto.

Gracias por la información.
Un saludo.

PD: una curiosidad, ¿cuantas horas dedicais, en vuestro tiempo libre, a delphiar, ya sea porque os estais haciendo una aplicacion, por probar caracteristicas del lenguaje o entorno, porque para ustedes programar es como para un pintor hacer un cuadro,....
Responder Con Cita
  #2  
Antiguo 07-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
Poder: 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
AL Gonzales (ahora si lo escribi bien )...
No, pero ya vas mejorando.


Cita:
Empezado por gushynet Ver Mensaje
no he probado el codigo, mas que nada porque prefiero primero entender bien como funciona el tema de la tabla virtual y realizar mi propio codigo ya que si no no se aprende
Es bueno que al final uno escriba o al menos comprenda todo el código que da solución a un problema, pero empezar por hacer pruebas con lo ya existente no me parece nada desventajoso, al contrario, es una forma muy buena de aprender.

Vuelvo a poner la función que da solución al problema que planteas:
Código Delphi [-]
{ Función para saber si Obj redefine el método Proc2.  Código para métodos
  virtuales abstractos y no abstractos. }
Function RedefineProc2 (Const Obj :TA) :Boolean;
Type
  TMetodo = Procedure Of Object;
Var
  Metodo :TMethod;
  EntradaVMT :Pointer;
Begin
  EntradaVMT := TA;

  Asm
    { De la VMT de TA, obtenemos la entrada que guarda la dirección del
      método Proc2 (cuando el método es abstracto, esa entrada contiene la
      dirección de memoria del procedimiento _AbstractError) }
    Add EntradaVMT, VMTOffset TA.Proc2
  End;

  TMetodo (Metodo) := Obj.Proc2;
  Result := Metodo.Code <> Pointer (EntradaVMT^);
End;
Donde dice Proc2, sólo debes poner el nombre del método en cuestión, y donde dice TA, el nombre de la clase base en cuestión. Por favor, pregunta por los elementos que te resulten desconocidos o confusos.


Cita:
Empezado por gushynet Ver Mensaje
De todas formas si a alguien le interesa lo que estoy haciendo no tiene nada mas que pedirme el codigo. Probablemente tendra algunos errores (poco optimizado o nada) pero creo que es una buena manera de conocer un poco las RTTI, asi que si alguien lo quiere...
Yo me apunto, en mi perfil está mi correo. Pero creo que sería mejor subirlo como archivo anexo, o al menos publicar las partes esenciales entre etiquetas "Delphi" dentro del mismo hilo, para que todo mundo pueda verlo sin mayor protocolo.


Cita:
Empezado por gushynet Ver Mensaje
el uso de las RTTI merman el rendimiento de una aplicación? la duda viene de que las funciones RTTI entiendo que tienen que navegar por la jerarquia de clases y eso debe ser desde un punto de vista computacional muy costoso? estoy en lo cierto?...
No. O al menos depende de qué información se la que consultes. Para lectura y comparaciones de punteros, como las anteriores, el consumo adicional de recursos no es significativo. Pero en el caso de propiedades publicadas que haya que consultar por su nombre expresado en un String, sí puede ser mayor. Sin embargo, al final de cuentas de penderá de cada situación en particular.


Cita:
Empezado por gushynet Ver Mensaje
con las RTTI he conseguido informacion sólo sobre propiades de la seccion published. Se puede ir mas lejos y poder conseguir en tiempo de ejecucion informacion sobre propiedades que esten en las otras secciones?

e informacion sobre variables?

por lo que he visto solo se permite para propiedades (y no variables) que esten declaradas en published, pero teniendo en cuenta la falta de documentacion sobre las RTTI a lo mejor si es posible obtener informacion de cualquier componente, sea simple o no, de un objeto.
En efecto, las propiedades deben ser publicadas (estar declaradas en la sección Published), pero además es necesario que la clase sea compilada bajo la directiva {$M+} (o su equivalente {$TypeInfo On}), o descienda de una clase que haya sido compilada con esa directiva. Es el caso, por ejemplo, de todos los derivados de TPersistent, cuya declaración dentro de la unidad Classes.pas (Delphi 7) es:
Código Delphi [-]
{$M+}

  TPersistent = class(TObject)
  private
    procedure AssignError(Source: TPersistent);
  protected
    procedure AssignTo(Dest: TPersistent); virtual;
    procedure DefineProperties(Filer: TFiler); virtual;
    function  GetOwner: TPersistent; dynamic;
  public
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); virtual;
    function  GetNamePath: string; dynamic;
  end;

{$M-}
Así mismo opté por declarar una clase recientemente en este otro caso, para que el compilador me generara información RTTI de una propiedad (ya que no basta que la propiedad sea publicada): http://www.clubdelphi.com/foros/show...6&postcount=12

Esto es lo que dice la ayuda sobre esa directiva:
Cita:
Type Switch

Syntax {$M+} or {$M-}
{$TYPEINFO ON} or {$TYPEINFO OFF}

Default {$M-}
{$TYPEINFO OFF}
Scope Local

The $M switch directive controls generation of runtime type information (RTTI). When a class is declared in the {$M+} state, or is derived from a class that was declared in the {$M+} state, the compiler generates runtime type information for fields, methods, and properties that are declared in a published section. If a class is declared in the {$M-} state, and is not derived from a class that was declared in the {$M+} state, published sections are not allowed in the class. Note that if a class is forward declared, the first declaration of the class must be declared with the $M switch.

When the $M switch is used to declare an interface, the compiler generates runtime type information for all properties and methods. That is, for interfaces, all members are treated as if they were published.

Note: The TPersistent class defined in the Classes unit of the component library is declared in the {$M+} state, so any class derived from TPersistent will have RTTI generated for its published sections. The component library uses the runtime type information generated for published sections to access the values of a component's properties when saving or loading form files. Furthermore, the IDE uses a component's runtime type information to determine the list of properties to show in the Object Inspector.

Note: The IInvokable interface defined in the System unit is declared in the {$M+} state, so any interface derived from IInvokable will have RTTI generated. The routines in the IntfInfo unit can be used to retrieved the RTTI.

There is seldom, if ever, any need for an application to directly use the $M compiler switch.
Cabe mencionar que Borland hace una sutil separación entre el término RTTI y otros que a veces asociamos con él, como VMT. Aunque en términos generales todo es Run Time Type Information (RTTI), la ayuda de Delphi emplea el término RTTI para referirse principalmente a la información que describe las partes publicadas de las clases. Mucha de esa información es obtenida con las funciones de la unidad TypInfo, y su origen se remonta a la primera versión de Delphi, para fines de almacenamiento y lectura de los componentes en los archivos DFM. Mecanismos de streaming que siguen vigentes.

Por otra parte, la Tabla de Métodos Virtuales (VMT) existe desde que Turbo Pascal vino a proponer destacadamente la programación orientada a objetos. Ya desde entonces Borland había diseñado una ingeniosa forma de guardar apuntadores a los métodos que podrían ser redefinidos (reimplementados) de una clase a otra dentro de la jerarquía. De tal forma que cada clase es en realidad su VMT, una tabla que la describe y que no sólo guarda punteros a métodos virtuales, sino una cantidad significativa de "meta código" adicional.

Estas VMTs y la información que contienen no dependen de si la clase está compilada con la directiva $TypeInfo o no, su información comprende elementos privados (Private), protegidos (Protected), públicos (Public) y publicados (Published). Pero algo de saber es que no guarda detalle de todos ellos, sino nada más de los que son "clave" para realizar ciertas tareas, como por ejemplo la finalización de campos ("variables" del objeto) que usan contadores de referencia, como es el caso de los campos de tipo String.


Cita:
Empezado por gushynet Ver Mensaje
PD: una curiosidad, ¿cuantas horas dedicais, en vuestro tiempo libre, a delphiar, ya sea porque os estais haciendo una aplicacion, por probar caracteristicas del lenguaje o entorno, porque para ustedes programar es como para un pintor hacer un cuadro,....
En mi caso, el tiempo libre es cuando juego baloncesto, leo un libro por gusto, doy un paseo por el parque o veo un filme. Todo lo que hago con Delphi, incluyendo el ayudar a otros, lo considero una responsabilidad, que asumo con gusto, claro.

Un abrazo en tiempo de ejecución.

Al González.

Última edición por Al González fecha: 07-02-2009 a las 22:19:49.
Responder Con Cita
  #3  
Antiguo 08-02-2009
gushynet gushynet is offline
Miembro
 
Registrado: ago 2008
Posts: 26
Poder: 0
gushynet Va por buen camino
Buenas, antes de poner el codigo, una preguna mas: 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 pues me llevaria un palo.


Saludos
Responder Con Cita
  #4  
Antiguo 08-02-2009
gushynet gushynet is offline
Miembro
 
Registrado: ago 2008
Posts: 26
Poder: 0
gushynet Va por buen camino
Aqui pongo los dos archivos basicos:

- TUniverso , es la clase base de la jerarquia que estoy haciendo--- aunque se llama TUniversoE_S.pas porque habia cambiado los metodos de E/S. De hecho esa parte no la he terminado porque me tropeze con la duda motivo de este hilo en el foro. Aunque podria haber continuado, encontre la duda interesante y deje un poco de lado lo que tenia entre manos para entender un poco las VTM. Por eso a los metodos de E/S mejor no hacerles caso

- Tipos --- define una serie de tipos de datos.


Saludos.


PD: ahora a machacar el codigo
Archivos Adjuntos
Tipo de Archivo: zip TUniverso.zip (9,4 KB, 3 visitas)
Responder Con Cita
  #5  
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
Poder: 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
  #6  
Antiguo 12-02-2009
gushynet gushynet is offline
Miembro
 
Registrado: ago 2008
Posts: 26
Poder: 0
gushynet Va por buen camino
Una pregunta mas. Situacion : tengo varios amigos que no programan en delphi sino en c++, VB, C#,....

Cual es la manera de compartir la jerarquia de clases que estoy implementando de forma que mis amigos pudieran declarar objetos de tipo TUniverso en sus programas? podría encapsularse en una dll y que ellos usaran la dll?

En el caso de que si pudiera compartir mi clase mis amigos podrían crearse clases descendientes de TUniverso? (creo que esto es imposible).

Saludos.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Saber que aplicacion tiene el foco Omega Varios 3 13-07-2008 17:36:01
Sobreescribir método Paint y saber coordenadas a refrescar Lord Delfos Gráficos 3 05-03-2008 13:48:28
saber si un field tiene el foco salvanano Conexión con bases de datos 0 08-05-2007 16:22:48
Como saber los dias que tiene un mes?? alfredosg19 Varios 3 06-03-2005 12:56:12
Saber si la Variable tiene letras cmgenny Varios 1 11-05-2004 08:00:59


La franja horaria es GMT +2. Ahora son las 04:45:24.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi