Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-03-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 18
Guillermo80 Va por buen camino
cabecera perdida para dll

Hola foreros, comento mi problema. Estoy preparando una dll a partir de un código que a tiene todos los .hy .c. Para ello me estoy creando todos los headers equivalentes en una unidad de Delphi, que será el lenguaje en el que voy a usar la dll, y sólo me queda uno por hacer, he aquí el problema. Llegado este punto, previo al gran problemón:

Cita:
struct FLAC__StreamEncoderProtected;
struct FLAC__StreamEncoderPrivate;

typedef struct {
struct FLAC__StreamEncoderProtected *protected_;
struct FLAC__StreamEncoderPrivate *private_;
} FLAC__StreamEncoder;
Total, que me lo defino en mi .pas de delphi, y ahora, cuando necesito los headers, encuentro el de FLAC__StreamEncoderProtected, pero el FLAC__StreamEncoderPrivate no está en un .h sino en un .c, lo cual me dejó un poco mosca.

Ahora resulta que es un registro enorme con montones y montones de campos, y que hace alusiones a no pocos tipos predefinidos en otros .h que no he incluido aún, y me resulta de lo más sospechoso todo esto, llevo la mitad traducido y me queda bastante aún, y no sé si lo estoy haciendo bien, por el hecho de no venir definido en un .h.

¿Qué sugerencia podríais darme?¿Hay que sacrificarse de lleno o hay alguna alternativa?

He estado mirando si realmente voy a usar todos los campos del registro, para definir sólo aquellos que necesite, pero resulta que en la función más importante hace:

Cita:
FLAC__StreamEncoder enconder;
encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate));
Por lo que reserva memoria para el registro private, que debe ser del tamaño que viene en el .c, así que me estropea el invento de "ahorrar campos".

Estoy desesperado, por favor, una ayuda quiero¡¡¡
Responder Con Cita
  #2  
Antiguo 12-03-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
No termino de entender del todo el problema, pero si defines FLAC__StreamEncoderPrivate como una estructura con menos campos...
Código:
calloc(1, sizeof(FLAC__StreamEncoderPrivate));
reservará espacio para esa estructura de menos campos...

De todas formas, una definición en C puede estar en una cabecera.h o en un .c. La diferencia está que si la defines en el .c o .cpp, solo sera reconocida en ese archivo y no será exportable a otros módulos, al menos en principio (hay trucos...). Esto quiere decir que esa definición que hechas en falta en una libreria.h tu la puedes predefinir, al traducirla, donde te venga bien, al fin y al cabo, las librerías.h no son otra cosa que archivos de declaración o predefinición.

Por otro lado no entiendo el empeño de traducir toda la dll, si al final estará compilada en una dll. ¿No es mas fácil y práctico hacer las llamadas oportunas desde delphi aunque la libreria original este en c++?. En fin, supongo que tus motivos tendrás.

Saludos.

Última edición por escafandra fecha: 13-03-2008 a las 00:54:08.
Responder Con Cita
  #3  
Antiguo 12-03-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 18
Guillermo80 Va por buen camino
No del todo

Bueno, realmente no estoy traduciendo toda la dll, sino solo aquellas cabeceras que vaya a utilizar en mi programa de Delphi las traduzco en una unidad .pas. Lo que pasa es que si traduzco una función que lleva una parámetro de entrada que sea FLAC__StreamEncoder, entonces me veo obligado a declarar ese registro, que a su vez tiene dos campos que son los registros FLAC__StreamEncoderProtected y FLAC__StreamEncoderPrivate, que a su vez me obliga a declarar sus contenidos. El tema de traducir todo esto es que esté más "accesible" a la hora de hacer las llamadas desde mi programa principal en Delphi que use esa dll (libFlac.dll).

Tengo una teoría: ¿podría ser que la declaración adelantada:

Cita:
struct FLAC__StreamEncoderProtected;
struct FLAC__StreamEncoderPrivate;
...me evite el tener que declarar en mi unidad .pas esos contenidos, y que se definan al hacer en una función de inicialización la instrucción (en un .c):

Cita:
FLAC__StreamEncoder encoder; //contiene los registros arriba mencionados sin definir
encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate));
...teniendo en cuenta que esta llamada se hace desde el .c en el que está definida correctamente FLAC__StreamEncoderPrivate? calloc reserva el espacio necesario para el FLAC__StreamEncoderPrivate definido en ese mismo .c, y lo asignaría a encoder->private que es el que está sin definir y que tras esa asignación hecha por calloc quedaría declarado y definido correctamente ?

No sé si es una chaladura esto que propongo, pero tiene bastante sentido, además, creo que fuiste tú, Escafandra, quien me habló del uso de la "declaración adelantada" en declaraciones de struct del tipo

Cita:
struct FLAC__StreamEncoderPrivate;
Responder Con Cita
  #4  
Antiguo 12-03-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Pues si lo unico que quieres traducir son las declaraciones externas de esa dll no te hace ninguna falta traducir nada mas que eso, es decir: sólo las funciones que tengas que usar en delphi, y que por lo tanto, el compilador debe conocer.

Si
Código:
struct FLAC__StreamEncoderProtected;
struct FLAC__StreamEncoderPrivate;
no las vas a llamar desde tu programa, y sólo son de uso interno.... No las traduzcas.

El hecho de que una declaración se realize en un *.c implica que no se va a usar desde otro archivo, de lo contrario el programador las declara en un *.h. En cpp puedes "incluir" (#include archivo.cpp) todo un archivo.c ó .cpp... Esto declararía todo lo declarado en ese archivo, pero no es ni habitual ni ortodoxo. De forma que es posible que no te haga falta declarar esas declaraciones hechas en tu archivo.c que comentabas en tu penúltimo post.

La forma se saberlo es compilar y llamar a tus funciones desde delphi. Si no tienes errores de compilación...

Saludos.

Última edición por escafandra fecha: 12-03-2008 a las 14:26:57.
Responder Con Cita
  #5  
Antiguo 12-03-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 18
Guillermo80 Va por buen camino
casi casi

Esos 2 registros no los uso directamente, pero el registro contenedor de ambos es un parámetro de entrada de una/s función que utilizo. Por tanto debería declarar ese registro contenedor. Si declaro el registro contenedor deberé declarar los registros que contengan, de ahí mi pregunta.

Pero si hago lo que tú me dices, y no declaro el registro contenedor, entonces el compilador no sabe de qué tipo es ese registro contenedor que le paso como parámetro a funciones de las que tengo declarada la cabecera en esa misma unidad.

Por favor, corrígeme si me equivoco.

Un saludo.
Responder Con Cita
  #6  
Antiguo 12-03-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Si el registro contenedor es un parámetro de una función que utilizas, entonces tu programa debe conocerlo, ya que le pasas el parámetro que previamente le has preparado.

Pero puede ser que ese parámetro lo obtengas de otra función de la dll y que realmente no interese saber como está definido... Piensa que
Código:
typedef struct {
    struct FLAC__StreamEncoderProtected *protected_;
    struct FLAC__StreamEncoderPrivate *private_;
} FLAC__StreamEncoder;
no es mas que una estructura de dos punteros, que bien podría ser
Código:
typedef struct {
    void *protected_;
    void *private_;
} FLAC__StreamEncoder;
Si a ti te da igual, al compilador también.

Otra posibilidad es extraer la declaración de ese.c que comentas y colocarla en una cabecera.

Saludos.
Responder Con Cita
  #7  
Antiguo 12-03-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 18
Guillermo80 Va por buen camino
me gusta

Me ha gustado la idea que propones, voy a aplicarla y voy a hacer algunas pruebas con una función de inicialización que usa la dichosa estructura a ver si funciona bien.

La 2ª idea que me propones es la versión "tediosa" que empecé haciendo, y que se iba convirtiendo en una "caja de pandora"; a cada campo que iba traduciendo le correspondía un tipo predefinido en otro header, que a su vez podía tener otro registro que...bla bla bla...y no acababa nunca.

Ya te comentaré si da resultado, muchas gracias por la ayuda¡¡
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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
fijar cabecera para tablas definidas en % Paco HTML, Javascript y otros 8 25-11-2005 12:51:37
Perdida de Informacion .. OJO IVAND Firebird e Interbase 5 23-11-2004 01:34:13
Perdida de } Jack Varios 5 06-05-2004 16:44:50
perdida de librerias¡¡¡ YolandaM Varios 3 06-05-2004 11:07:22
perdida de datos Esau SQL 0 03-07-2003 16:13:03


La franja horaria es GMT +2. Ahora son las 23:34:11.


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