Ir al contenido


Foto

Concepto: RTTI (RunTime Type Information)


  • Por favor identifícate para responder
7 respuestas en este tema

#1 defcon1_es

defcon1_es

    Member

  • Miembros
  • PipPip
  • 19 mensajes
  • LocationEspaña

Escrito 28 mayo 2009 - 08:49

Bueno, después de leerme todos los posts de esta sección, se me ha ocurrido abrir este tema.
Hace sólo una semana que he empezado a usar RTTI, y me ha dejado alucinado lo que se puede hacer con RTTI.

Aqui dejo un par de enlaces sobre el tema, mientras saco tiempo para traducirlos:
http://www.blong.com...iRTTI/CB140.htm
http://delphi.about..../delphirtti.htm
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.261 mensajes
  • LocationMéxico

Escrito 28 mayo 2009 - 08:55

Muy interesante amigo, le daremos una leí­da a ver que tal y publicar comentarios al respecto.

Salud OS
  • 0

#3 defcon1_es

defcon1_es

    Member

  • Miembros
  • PipPip
  • 19 mensajes
  • LocationEspaña

Escrito 28 mayo 2009 - 09:05

He tenido que usar RTTI en este caso:
Trabajo con un proyecto "monstruoso", y al compilar con Delphi 6, hay veces que da AV en los sitios más dispares, como en rtl60.bpl o ntdll.dll y lo peor es que en algunos módulos de datos, los componentes pierden su enlace con el componente IBDatabase (y IBTransaction).

Como es tan grande el proyecto y usa multitud de componentes enlazados a datos de distintas clases, para recuperar el enlace al objeto IBDatabase en ejecución y evitar los mensajes del tipo "Database not assigned", me pregunté si habrí­a alguna forma de asignar el objeto IBDataBase a todos esos componentes. Ahí­ es donde interviene la RTTI.

En vez de hacer esta "locura" o algo peor:


delphi
  1. // A lo bestia !!
  2.   for i:=0 to (TDataModule(Sender).ComponentCount - 1) do
  3.   begin
  4.     if (Dm.Components[i] is TpgIBDataSet)
  5.     then begin
  6.       TpgIBDataSet(Dm.Components[i]).Database := DatosSesion.BaseDatosGESTION5;
  7.       TpgIBDataSet(Dm.Components[i]).Transaction := DatosSesion.IBTransaccion;
  8.     end;
  9.     if (Dm.Components[i] is TpgIBQuery)
  10.     then begin
  11.       TpgIBQuery(Dm.Components[i]).Database := DatosSesion.BaseDatosGESTION5;
  12.       TpgIBQuery(Dm.Components[i]).Transaction := DatosSesion.IBTransaccion;
  13.     end;
  14.     if (Dm.Components[i] is TpgIBStoredProc)
  15.     then begin
  16.       TpgIBStoredProc(Dm.Components[i]).Database := DatosSesion.BaseDatosGESTION5;
  17.       TpgIBStoredProc(Dm.Components[i]).Transaction := DatosSesion.IBTransaccion;
  18.     end;
  19.  
  20.   // Y demás clases que se usan, como TIBDataSet, TIBQuery, TIBSQL, etc.
  21.   end;



Lo solucioné así­:



delphi
  1. procedure Reasignar_enlace_BaseDatos(Dm: TDataModule);
  2. var i:Integer;
  3.   PropInfo: PPropInfo;
  4. begin
  5. // Rutina para evitar que los TpgIBDataSet, TpgIBQuery, TpgIBStoredProc
  6. // pierdan su enlace con el componente de Base de Datos
  7. // debido a errores al cerrar el Delphi (Access Violation)
  8.  
  9. // Para ello uso RTTI de Delphi, que permite buscar/leer/modificar propiedades en los componentes
  10. // 1.-Se recorren todos los objetos del módulo de datos que viene como parámetro
  11.   for i:=0 to (Dm.ComponentCount - 1) do
  12.   begin
  13. // 2.-Buscamos si el componente tiene la propiedad 'Database'
  14.     PropInfo := TypInfo.GetPropInfo(Dm.Components[i].ClassInfo, 'Database') ;
  15.     if Assigned(PropInfo)
  16.     then begin
  17. // 3.-Damos el valor que queremos a la propiedad 'Database'
  18.       TypInfo.SetOrdProp(Dm.Components[i], PropInfo, LongInt(DatosSesion.BaseDatosGESTION5));
  19. // 4.-Buscamos si el componente tiene la propiedad 'Transaction'
  20.       PropInfo := TypInfo.GetPropInfo(Dm.Components[i].ClassInfo, 'Transaction') ;
  21.       if Assigned(PropInfo) then
  22. // 5.-Damos el valor que queremos a la propiedad 'Transaction'
  23.         TypInfo.SetOrdProp(Dm.Components[i], PropInfo, LongInt(DatosSesion.IBTransaccion));
  24.     end;
  25.   end;



  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.261 mensajes
  • LocationMéxico

Escrito 28 mayo 2009 - 09:14

Vaya que bien, imagino que la clase PPropInfo la creaste tu ¿verdad?

Como la definiste (si se puede saber)

Salud OS


  • 0

#5 defcon1_es

defcon1_es

    Member

  • Miembros
  • PipPip
  • 19 mensajes
  • LocationEspaña

Escrito 28 mayo 2009 - 09:19

No, esa clase (realmente es un puntero) está definida en TypeInfo.pas de esta forma:


delphi
  1.   PPropInfo = ^TPropInfo;
  2.  
  3.   TPropInfo = packed record
  4.     PropType: PPTypeInfo;
  5.     GetProc: Pointer;
  6.     SetProc: Pointer;
  7.     StoredProc: Pointer;
  8.     Index: Integer;
  9.     Default: Longint;
  10.     NameIndex: SmallInt;
  11.     Name: ShortString;
  12.   end;


  • 0

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.261 mensajes
  • LocationMéxico

Escrito 28 mayo 2009 - 09:28

Ah ok, perfecto, esto es muy interesante. Lo dicho, a estudiarle para poder comentar :)

Salud OS

PD, no estarí­a nada mal que nos aportaras con un tutorial amigo, dejanos saber si te animas para crearte un acceso al foro de borradores donde puedas ir creandolo y cuando decidas publicarlo.
  • 0

#7 defcon1_es

defcon1_es

    Member

  • Miembros
  • PipPip
  • 19 mensajes
  • LocationEspaña

Escrito 28 mayo 2009 - 09:38

Gracias egostar, de buenas intenciones estoy lleno,
pero dispongo de poco tiempo para ello (ahora mismo estoy en el trabajo y mi jefe no está),
y cuando salgo de trabajar sobre las 19:00, tengo una niña pequeña que consume el 98% de mi tiempo, de 23:30 a 01:00 + o - me dedico a estudiar para unas oposiciones de la Junta de Castilla-La Mancha, pero prometo que revisaré los libros de la Guí­a de Desarrollo Delphi 5 de Steve Teixeira y Xavier Pacheco para hacer un tutorial sobre RTTI.
  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.261 mensajes
  • LocationMéxico

Escrito 28 mayo 2009 - 10:17

Gracias egostar, de buenas intenciones estoy lleno,
pero dispongo de poco tiempo para ello (ahora mismo estoy en el trabajo y mi jefe no está),
y cuando salgo de trabajar sobre las 19:00, tengo una niña pequeña que consume el 98% de mi tiempo, de 23:30 a 01:00 + o - me dedico a estudiar para unas oposiciones de la Junta de Castilla-La Mancha, pero prometo que revisaré los libros de la Guí­a de Desarrollo Delphi 5 de Steve Teixeira y Xavier Pacheco para hacer un tutorial sobre RTTI.


No te preocupes amigo, primero lo primero (y) no corre prisa.

Salud OS
  • 0