FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
||||
|
||||
Puntero a función
Hola foreros, tengo un problema al traducir una cabecera de una función de Visual C++, la cual es un puntero a una función. He mirado cómo debería hacerse pero me salen errores de compilación que no consigo resolver. La "original" es la siguiente:
Cita:
Cita:
|
#2
|
||||
|
||||
Hola Guillermo80,
¿Deseas traducir de Visual C++ a Delphi? No se Visual C++ pero un puntero a función o procedimiento en Delphi es así:
De modo que si tenemos una función cualquiera que cumpla con dicha descripción de tipos y argumentos podemos hacer cosas como esta:
No se si se entiende. Saludos, |
#3
|
||||
|
||||
de momento no sale
Hola Delphius, gracias por los ejemplos, se parece a lo que quiero hacer pero aún aplicando como me dices no me termina de salir. Para que entiendas un poco el contexto, se trata de un código en una Unit.pas que hace referencia a una librería compilada en Visual C++, de ahí el querer traducir la cabecera de este método. Este puntero a funcion es a su vez un parámetro de entrada de otra función que es la que hace uso de la dll. Finalmente mi código ha quedado como sigue:
Cita:
|
#4
|
||||
|
||||
¡Hola!
Me gustaría añadir que ese tipo de dato se conoce como procedimental (en inglés procedural). Es recomendable tomar en cuenta el ejemplo dado por Marcelo, Guillermo. Aunque en este caso, el nombre original del tipo de dato indica que se trata de una función de retrollamada (callback). Este tipo de funciones generalmente no son llamadas explícitamente desde nuestro código, sino que se las proporcionamos a otra función para que ésta se encargue de llamarlas. Las funciones de retrollamada son similares a los eventos, en el sentido de que proporcionamos una rutina de código para que un proceso ya escrito, al ser ejecutado, llame a nuestra rutina cada vez que suceda algo en particular. Es usual encontrarlas en muchas APIs que usan estas funciones de retrollamada para "avisarnos" o "actualizarnos" información, algunas veces en procesos iterativos. Por la sintaxis nativa, me parece bien definir a tu función de retrollamada como procedimiento. Sólo habría que averiguar qué convención de llamada utiliza, indicándolo con la palabra reservada correspondiente: Register, Pascal, CDecl, StdCall, SafeCall (ver tema "Calling conventions" en la ayuda de Delphi). Por último comento que no es necesario usar la palabra Pointer para indicar que nuestra variable o tipo de dato es procedimental. En Pascal es implícito que un valor procedimental es la dirección de memoria (puntero) de la primera instrucción de código máquina de una rutina —es a esa dirección a donde "salta" la CPU para ejecutarla—. Mi aportación. Al González. P.D. También te sugiero, Guillermo, llamarle a estas APIs o DLLs bibliotecas en lugar de "librerías". Es más correcto. |
#5
|
||||
|
||||
Hola Al, muchas gracias por esta clase magistral , me aclara bastante las ideas de lo que estoy manejando, ya que había cosas que no tenía clara.
He estado mirando un poco más a fondo las directivas y en este caso creo que está claro que se usa register, que es la que permite definir tipos con parámetros. Así que ahora lo tengo definido así, pero aún así no me funciona: Cita:
|
#6
|
||||
|
||||
Cita:
Saludos, |
#7
|
||||
|
||||
Cita:
El error que te aparece seguramente es Unknown directive: 'FLAC__StreamEncoderProgressCallback'. Habla bien de un forista mostrar el mensaje exacto de error que le aparece en pantalla, más que una interpretación personal (y a veces equivocada) del mismo. Ese error aparece porque le estás dando el nombre del tipo de dato después de la palabra Procedure; basta con que el nombre aparezca una sola vez delante (a la izquierda) del signo de igual ("="), como ya lo está ahí. Después de "Procedure" deben ir los parámetros entre paréntesis, es decir, la cabecera. Por otro lado, desconozco por qué declaras la variable funcCallback (tendría que ver tu código para decirte si realmente la requieres). Lo que sí debes de tener claro, Guillermo, es que debes* crear un procedimiento con la misma cabecera que define TFLAC__StreamEncoderProgressCallback, para poder darle ese procedimiento a la función que lo espera como parámetro. Ese procedimiento que vas a crear, es tu rutina de retrollamada. *¿Qué dice la documentación de la biblioteca? ¿Forzosamente debes proporcionar ese procedimiento? Algunas veces las funciones de retrollamada son opcionales. Espero haber orientado. Al González. Última edición por Al González fecha: 31-03-2008 a las 00:57:43. |
#8
|
||||
|
||||
Hola Al, muchas gracias por tu aportación, sin duda está siendo muy valiosa para mí.
He aplicado las cosas como me dijiste y efectivamente, ya compila y ejecuta, pero hay alguna cosa que no tengo clara. La función de retrollamada tienes razón, es opcional, y le puedo pasar un nil a la función principal en el parámetro de la función de retrollamada, pero finalmente la he incluido. Mi código ha quedado como sigue de forma resumida: Cita:
Cita:
Cita:
¿Tendría que crear un procedimiento con otro nombre?¿Cómo lo usaría para poder "alimentar" mi función principal correctamente? En VisualC lo hace así: Cita:
Un saludo. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
¿puntero a puntero? | Guillermo80 | Varios | 3 | 09-03-2008 22:46:32 |
puntero | gaston260 | API de Windows | 11 | 01-02-2008 22:39:20 |
uso de función de dll cuyo parametro es un puntero (dirección) a una estructura | abracadabra | Varios | 1 | 12-10-2007 16:43:59 |
pasar un puntero a una funcion | baby | Varios | 2 | 21-05-2007 13:10:22 |
puntero a imagen | Abaddon | Gráficos | 9 | 16-06-2005 00:17:29 |
|