¡Hola!
Cita:
Empezado por Al González
MethodAddress sólo[*] funciona con métodos publicados.
|
* Esto que he comentado en algunas ocasiones dejó de ser completamente cierto, al menos desde Delphi 7. Si bien es verdad en la gran mayoría de los casos, y la misma ayuda de Delphi 7 lo señala sin insinuar otra cosa:
Cita:
If Name does not specify a published method for the object, MethodAddress returns nil.
|
Lo cierto es que al menos desde esa versión existe una directiva de compilación poco conocida y escasamente documentada, de nombre
$MethodInfo. Con ella puede generarse RTTI
también para métodos públicos. Pero va más allá: esta directiva además agrega información sobre los parámetros, la convención de llamada y el tipo de dato que los métodos devuelven, es decir, una descripción detallada de cada método que la clase compilada con esa directiva (o cualquiera de sus descendientes) tenga en las secciones
Public y
Published.
Esto lo descubrí la mañana de ayer, durante una breve investigación relacionada con un trabajo que estoy realizando, gracias a este par de referencias:
http://hallvards.blogspot.com/2006/0...lass-rtti.html
http://davidglassborow.blogspot.com/...lass-rtti.html
Por cierto, el noruego
Hallvard tiene publicados en su bitácora una buena cantidad de artículos altamente reveladores para quienes sentimos más que curiosidad por la RTTI.
Esta es una pequeña prueba que hice para verificar que aun con métodos públicos es posible usar
MethodAddress:
Código Delphi
[-]
type
{$MethodInfo On}
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
Procedure Proc1; Virtual; Abstract;
Protected
Procedure Proc2; Virtual; Abstract;
public
Procedure ProcA; Virtual; Abstract;
end;
{$MethodInfo Off}
TF2 = Class (TForm1)
Public
Procedure ProcB; Virtual; Abstract;
End;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage (IntToStr (Integer (MethodAddress ('Proc1'))));
ShowMessage (IntToStr (Integer (MethodAddress ('Proc2'))));
ShowMessage (IntToStr (Integer (MethodAddress ('ProcA'))));
ShowMessage (IntToStr (Integer (TF2.MethodAddress ('ProcB'))));
Close;
end;
Copio esta información del artículo de Glassborow, para tener muy en cuenta:
Cita:
Empezado por online documentation
The $METHODINFO switch directive is only effective when runtime type information (RTTI) has been turned on with the {$TYPEINFO ON} switch. In the {$TYPEINFO ON} state, the $METHODINFO directive controls the generation of more detailed method descriptors in the RTTI for methods in an interface. Though {$TYPEINFO ON} will cause some RTTI to be generated for published methods, the level of information is limited. The $METHODINFO directive generates much more detailed (and much larger) RTTI for methods, which describes how the parameters of the method should be passed on the stack and/or in registers. There is seldom, if ever, any need for an application to directly use the $METHODINFO compiler switch. The method information adds considerable size to the executable file, and is not recommended for general use.
|
Un abrazo público.
Al González.