FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
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 |
#2
|
||||
|
||||
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; 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. |
#3
|
|||
|
|||
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 |
#4
|
||||
|
||||
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. |
#5
|
||||
|
||||
Cita:
Saludos!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#6
|
||||
|
||||
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. |
#7
|
||||
|
||||
Cita:
Cita:
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. |
#8
|
||||
|
||||
Hola,
esto es un pequeño resumen del help de delphi, en referencia a la RTTI: Cita:
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. |
#9
|
||||
|
||||
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; 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 |
#10
|
|||
|
|||
¿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. |
#11
|
||||
|
||||
[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 |
#12
|
||||
|
||||
Hola Roman,
Cita:
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. |
#13
|
||||
|
||||
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. |
#14
|
||||
|
||||
Cita:
Saludos! |
|
|
|