Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-07-2003
Rudorf Rudorf is offline
Registrado
 
Registrado: jul 2003
Ubicación: Sevilla (España)
Posts: 5
Poder: 0
Rudorf Va por buen camino
Exclamation Direccion de memoria de una funcion cuyo nombre esta en una variable

Buenas, necesito ayuda para pasar la direccion de una funcion a una variable puntero. El problema es que el nombre de la funcion está dentro de una variable y no se como pasarlo.

Nombrefuncion:='MiFuncion';
VPuntero:=addr(Nombrefuncion); // Algo similar a esto busco

Si a Addr le paso MiFuncion en vez de Nombrefuncion, funciona perfectamente, el problema es que no tengo más remedio que hacerlo como lo describo.

Si alguien lo sabe o sabe que no se puede, respondame al mail.
GRACIAS
Responder Con Cita
  #2  
Antiguo 29-07-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 21
__marcsc Va por buen camino
Hola,

piensa que esto es una cosa poco natural, y sería conveniente que tuvieras un buen motivo para hacerlo...

Lo que puedes hacer, en teoría, es conocer la dirección de un método publicado de un objeto, gracias a la función de clase MethodAddress de la clase TObject.

Código:
class function MethodAddress(const Name: ShortString): Pointer;
Si eso no te sirve dudo mucho que puedas hacerlo, recuerda que Delphi es un lenguaje compilado y por tanto para hacer eso que tu quieres el compilador debería generar esa información (que yo sepa no lo hace).

Lo que hace esa función de la clase TObject puede hacerse gracias a la RTTI (Runtime Type Information) que se mantiene de cada objeto. Concretamente esa función es utilizada por el sistema de streaming de Delphi, es decir, se utiliza cuando se lee de un fichero dfm, ya que de allí se lee un nombre de procedimiento (publicado) que debe poder traducirse en una dirección de memoria.

Espero una contestación

Saludos.
Responder Con Cita
  #3  
Antiguo 30-07-2003
Rudorf Rudorf is offline
Registrado
 
Registrado: jul 2003
Ubicación: Sevilla (España)
Posts: 5
Poder: 0
Rudorf Va por buen camino
Talking

Pues muy bien, me ha funcionado y me ha sacado de un buen apuro.

Matizo que la funcion o procedimiento debe estar declarada public o published para que funcione correctamente el MethodAddress.

Un saludo y GRACIAS
Responder Con Cita
  #4  
Antiguo 30-07-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 21
__marcsc Va por buen camino
Pues gracias por el matiz, no sabía que funcionaba con métodos public (en el help dice que solamente funciona con published, y la verdad nunca he utilizado el método )

Un saludo y me alegro que te haya servido.
Responder Con Cita
  #5  
Antiguo 30-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Cita:
Posteado originalmente por marcsc
Lo que hace esa función de la clase TObject puede hacerse gracias a la RTTI (Runtime Type Information) que se mantiene de cada objeto.
Dudo mucho esto, pues este método de clase pertenece a TObject que es una clase que no guarda "Run Time Type Information", y si lo implementamos en una clase heredada de TObject, funciona de todos modos. (Empezó el debate? )

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #6  
Antiguo 30-07-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 21
__marcsc Va por buen camino
Esto es la guerra!!

cierto lo que dices, no se guarda RTTI de TObject porqué no tiene miembros published

Lo que me despistó, y lo que en parte no comprendo es que el propio help comenta que solo es válido para miembros published. Por tanto si es published es que se genera RTTI (dado que en teoría esta es la diferencia entre public y published). Además, si las funciones sirven para hacer el streaming de un dfm, que sentido tiene que estén disponibles a partir de TObject? No sería más lógico que estuviera disponible a partir de TComponent? Ya que, en un dfm solo se almacenan propiedades publicadas, que son las que aparecen en el Object Inspector, no? Quizás puede ser que interese que yo tenga propiedades publicadas aunque no sea un componente. Pero aún así, Delphi no podría guardarlos automáticamente en el dfm a menos que no derivara de TComponent, no?

Saludos!

Última edición por __marcsc fecha: 30-07-2003 a las 16:34:53.
Responder Con Cita
  #7  
Antiguo 30-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Cita:
Posteado originalmente por marcsc
cierto lo que dices, no se guarda RTTI de TObject porqué no tiene miembros published
Te paso un fragmento de un artículo que escribí hace ya tiempo:
Cita:
...Las clases que al compilar generan la RTTI, son aquellas que han sido declaradas bajo la directiva {$M} y todas las clases heredadas de estas, por ejemplo TPersistent con esta directiva, esto implica que todas las clases heredadas de TPersistent generarán RTTI y podremos acceder a la lista de propiedades publicadas en tiempo de diseño y ejecución...
Entre tantas cosas MethodAddress la debe utilizar el TReader cuando lee el DFM del form, recordemos que el código que se encuentra en el DFM no se compila, lo que a mi parecer es una pequeña desventaja del lenguaje.

Saludos!!

PD:
¡¡¡¡Será guerra!!!!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.

Última edición por delphi.com.ar fecha: 31-07-2003 a las 16:03:14.
Responder Con Cita
  #8  
Antiguo 31-07-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 21
__marcsc Va por buen camino
Hola,

esto es un pequeño resumen del help de delphi, en referencia a la RTTI:

Cita:
Los miembros publicados tienen la misma visibilidad que los públicos. La diferencia es que se genera RTTI para los miembros publicados

...


Una clase no puede tener métodos publicados a menos que sea compilada con la directiva {$M+} o que descienda de una clase compilada con la directiva {$M+}. La mayoría de las clases descienden de TPersistent que está compilada con esta directiva por lo que no es necesario añadirla.
Con esto lo único que quiero decir es que la RTTI se genera porque hay algun miembro de la clase con visibilidad published. Para que esto sea posible es necesario añadir la directiva {$M+}, pero no por añadir esta directiva se generará RTTI de miembros no published.

Repito esto está sacado del help de Delphi, ignoro completamente si es verdadero o falso, pero al menos tiene sentido para mi

La guerra continua

Saludos!!

Última edición por __marcsc fecha: 31-07-2003 a las 01:28:37.
Responder Con Cita
  #9  
Antiguo 31-07-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Un pequeño apunte. De acuerdo con Rudorf MethodAddress funciona para métodos públicos o publicados. Sin embargo una pequeña prueba me mostró lo contrario:

Código:
TFoo = class
published
  function Doo: Integer;
end;

...

procedure TForm1.Button1Click(Sender: TObject);
var
  Foo: TFoo;

begin
  Foo := TFoo.Create;
  if Foo.MethodAddress('Doo') <> nil then
    Beep;

  Foo.Free;
end;
El botón hace beep pero se queda mudo si cambiamos published por public

En el primer caso, por cierto, noten que no hay directiva $M de forma que se compila con el default {$M-} de manera que no se genera RTTI (como se comprueba viendo que Foo.ClassInfo es nil) lo cual demuestra que MethodAddress funciona sin usar RTTI.

// Saludos
Responder Con Cita
  #10  
Antiguo 31-07-2003
Rudorf Rudorf is offline
Registrado
 
Registrado: jul 2003
Ubicación: Sevilla (España)
Posts: 5
Poder: 0
Rudorf Va por buen camino
¿Public o Pubished? This is the question

Roman, pues a mi me está funcionando ahora con published, y lo probé con public y tambien iba.

Tengo lo siguiente:

type Cambios=class (TObject)
published
procedure TAG15_Change();
end;

...

type Tag = class (TObject)
PUBLIC
TagChange: procedure();
end;

...

Constructor de Tag
ProcName:=TAGName + '_Change'; // TAG15_Change
TagChange:=Vcambio.methodAddress(ProcName);

...

Evento click de un botón
// TAGLIST de la clase Tag
TAGLIST.TagChange; // LLama al procedimiento TAG15_Change

No se si me he explicado bien

Última edición por Rudorf fecha: 31-07-2003 a las 07:34:30.
Responder Con Cita
  #11  
Antiguo 31-07-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
[modo=dudoso]
No estoy muy convencido del cambio al foro de debates ya que el último mensaje de Rudorf así como la respuesta que doy me parece que regresan el hilo a sus orígenes.

De cualquier forma aquí va la respuesta
[/modo]

No indicas de qué tipo es la variable VCambio pero, a juzgar por la nomenclatura, supongo que es de tipo Cambios que declara el método TAG15_Change como publicado. El que TagChange sea público no tiene nada que ver ya que el punto aquí es si el método MethodAddress funciona o no si el parámetro es el nombre de un método público o publicado. De hecho, si te fijas podrías asignar el resultado de Vcambio.methodAddress incluso a una variable privada de la clase Tag y, me arriesgo a decir, incluso a una variable cualquiera, esto es, un puntero que no forme parrte de una clase.

Por otra parte, si no te va mal, me agradaría que nos contaras el propósito de lo que estás haciendo. Por un lado me llama la atención; pareciera que intentas asignar eventos "OnChange" a ciertos controles pero no alcanzo a entender el papel de la clase Cambios. Por otro lado, muchas preguntas relacionadas con obtener variables o procedimientos a partir de su nombre provienen de personas acostumbradas a lenguajes interpretados como VB o Clipper por lo cual quizá no sepan que hay otras técnicas posiblemente más eficientes y "elegantes" de hacer lo mismo en un lenguaje compilado como Delphi.

// Saludos
Responder Con Cita
  #12  
Antiguo 31-07-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 21
__marcsc Va por buen camino
Hola Roman,

Cita:
Posteado originalmente por roman
lo cual demuestra que MethodAddress funciona sin usar RTTI.
esto ya me lo vi venir cuando delphi.com.ar hizo notar que es un método de TObject, clase de la cual no se genera RTTI.

Lo que yo digo, y que fue lo que me hizo despistar, aunque visto ahora es un hecho independiente, es qué sentido puede tener la existencia de este método en la clase TObject si funciona para métodos published.

Al principio pensaba que seria más lógico que estuviera disponible a partir de TComponent, ya que en teoría solamente se pueden guardar propiedades en un dfm a partir de TComponent (dado que sinó ni tan solo aparecen en el IDE). Recordemos que el help de Delphi dice que no debería haber necesidad de llamar este método directamente ya que Delphi lo utiliza internamente para streaming. ¿Entonces porqué en TObject? ¿No sería más lógico en TComponent o haciendo alguna concesión más en TPersistent que ya está compilada con la directiva {$M+}?

La respuesta radica en que aunque el Delphi no lo necesite hasta TComponent sí que puede ser que a nosotros nos interese hacerlo antes (como es el caso de Rudorf). De hecho, viendolo de este modo TObject es el sitio adecuado ya que significa que podemos crear un descendiente directo que publique algun miembro y utilizar este método.

Saludos.
Responder Con Cita
  #13  
Antiguo 31-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Ahhhhh... ¡¡Los hice investigar!!
Sabía que se iba a sumar Román en este tema...


Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #14  
Antiguo 31-07-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 21
__marcsc Va por buen camino
Cita:
Posteado originalmente por delphi.com.ar
Ahhhhh... ¡¡Los hice investigar!!
Sabía que se iba a sumar Román en este tema...
Yo también, y aún sabiendo que está de vacaciones y ahora mismo su principal ocupación es contar chistes de elefantes

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


La franja horaria es GMT +2. Ahora son las 16:49:06.


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