Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Acceso a DLL

Hola.

Estoy desarrollando un motor para jugar a las damas españolas http://www.terra.es/personal9/aggg63/damas/damas.htm con la interficie CheckerBoard http://www.fierz.ch/checkers.htm de Martin Fierz. Ed Gilbert ha desarrollado una DLL que accede a las bases de datos de finales de las damas americanas http://pages.prodigy.net/eyg/Checkers/egdb_rev3.zip. He creado un pequeño programa que intenta acceder a las bases de datos, pero no me carga bien las funciones que exporta la DLL. A continuacion teneis un resumen de las unidades que uso. La primera funcion me identifica la base de datos pero cuando intento abrir un handle con la segunda, me da un error. ¿Alguien puede ayudarme un poco? Gracias.

Código Delphi [-]
 unit uTiposEGDB;
 
 interface
 
 const
   // Color definitions
   EGDB_BLACK = 0; EGDB_WHITE = 1;
   // Values returned by handle->lookup()
   EGDB_UNKNOWN = 0; // value not in the database
   EGDB_WIN = 1; EGDB_LOSS = 2; EGDB_DRAW = 3;
   EGDB_NOT_IN_CACHE = 4; // conditional lookup and position not in cache
   // MTC macros
   MTC_THRESHOLD = 10; MTC_LESS_THAN_THRESHOLD = 1;
   MTC_UNKNOWN = 0;
 
 type
   // Tipos de tablas de finales
   EGDB_TYPE = ( EGDB_KINGSROW_WLD=0, EGDB_KINGSROW_MTC,
   EGDB_CAKE_WLD, EGDB_CHINOOK_WLD,
   EGDB_KINGSROW32_WLD, EGDB_KINGSROW32_MTC,
   EGDB_CHINOOK_ITALIAN_WLD, EGDB_KINGSROW32_ITALIAN_WLD,
   EGDB_KINGSROW32_ITALIAN_MTC);
   // for database lookup stats
   EGDB_STATS = record
   lru_cache_hits,lru_cache_loads,autoload_hits,db_requests,
   db_returns, db_not_present_requests: cardinal;
 end;
 
   EGDB_BITMAP_TYPE = (EGDB_NORMAL=0, EGDB_ROW_REVERSED);
   // This is KingsRow's definition of a checkers position.
   EGDB_NORMAL_BITMAP = record
   black,white,king: cardinal;
 end;
 
   // This is Cake's definition of a board position.
   EGDB_ROW_REVERSED_BITMAP = record
   black_man,black_king,white_man,white_king: cardinal;
 end;
 
   EGDB_BITMAP = record
   case integer of
     0: (normal: EGDB_NORMAL_BITMAP);
     1: (row_reversed: EGDB_ROW_REVERSED_BITMAP);
   end;
   PEGDB_BITMAP = ^EGDB_BITMAP;
   PEGDB_STATS = ^EGDB_STATS;
   // The driver handle type
   PEGDB_driver = ^TEGDB_driver;
   TEGDB_driver = record
   lookup: function (handle: PEGDB_driver; position: PEGDB_BITMAP;
   color: integer; cl: integer):longint; cdecl;
   reset_stats: procedure (handle: PEGDB_driver);
   get_stats: function (handle: PEGDB_driver): PEGDB_STATS;
   verify: function (handle: PEGDB_driver): integer;
   close: function (handle: PEGDB_driver): integer;
   internal_data: pointer;
 end;
 
 type
   TFMensajes = procedure(texto: pAnsiChar); cdecl;
 
 var
   FicheroTexto: TextFile;
   HandleDLL: THandle;
   function IdentificarTablaFinales(directory: pAnsiChar;
     var db_type: EGDB_TYPE; var max_pieces: Integer):integer; stdcal;
   function AbrirTablaFinales(bitmap_type: EGDB_BITMAP_TYPE; pieces,
     cache_mb: Integer;directory: pAnsiChar; FMensajes: TFMensajes) : PEGDB_DRIVER;
       cdecl; external 'egdb.dll' index 6;
 
 procedure FMensaje(texto: pAnsiChar); cdecl;
 begin
   AssignFile(FicheroTexto,'FicheroEGDB.txt');
   Rewrite(FicheroTexto);
   Write(FicheroTexto,texto);
   CloseFile(FicheroTexto);
 end;
 
 function CargarFuncionDLL(FicheroDLL: String; var HandleDLL:
   THandle; Nombre: String; Indice: Integer=-1) :Pointer;
 begin
   Result:=nil;
   HandleDLL:=0;
   HandleDLL:=LoadLibrary(pAnsiChar(FicheroDLL));
   If HandleDLL=0 then Exit;
   If Indice<0 then
     Result:=GetProcAddress(HandleDLL,pAnsiChar(Nombre))
   else
     Result:=GetProcAddress(HandleDLL,pAnsiChar(Indice));
 end;
 
 function DescripcionTipoEGDB(tipo: EGDB_TYPE):string;
 begin
   case tipo of
     EGDB_KINGSROW_WLD: result:='KingsRow WLD';
     EGDB_KINGSROW_MTC: result:='KingsRow MTC';
   end;
 end;
 
 procedure TForm1.btnIdentificarTFClick(Sender:TObject);
 var
   directorio: pAnsiChar;
   TipoEGDB: EGDB_TYPE;
   HandleEGDB: PEGDB_DRIVER;
   piezas: Integer;
   tipo: Integer;
   FMensajes: TFMensajes;
 begin
   HandleDLL:=LoadLibrary('egdb.dll');
   IdentificarTablaFinales:=CargarFuncionDLL'egdb.dll',HandleDLL,'egdb_identify');
   directorio:='c:\damas\damas\egdb\cake';
   IdentificarTablaFinales(directorio,TipoEGDB,piezas);
   memResultados.Lines.Add('Tipo EGDB: '+DescripcionTipoEGDB(TipoEGDB));
   memResultados.Lines.Add('Piezas: '+inttostr(piezas));
   AbrirTablaFinales:=CargarFuncionDLL('egdb.dll',HandleDLL,'egdb_open',6);
   // ERROR AL EJECUTAR LA SIGUIENTE LINEA
   HandleEGDB:=AbrirTablaFinales(EGDB_NORMAL,piezas,300,directorio,FMensajes);
   FreeLibrary(HandleDLL);
 end;

Última edición por dec fecha: 03-09-2005 a las 17:19:21. Razón: (Encerrar el código en la etiqueta DELPHI)
Responder Con Cita
  #2  
Antiguo 03-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Correccion a las unidades

Eliminar la linea

HandleDLL:=LoadLibrary('egdb.dll');

del procedimiento

procedure TForm1.btnIdentificarTFClick(Sender:TObject);

Disculparme, estoy usando 2 formas de acceder a la libreria y se ha colado codigo que no uso ahora.
Responder Con Cita
  #3  
Antiguo 03-09-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

aggg63, he editado tu mensaje para encerrar el código fuente dentro de la etiqueta [ DELPHI ]. Por favor, en sucesivas ocasiones utiliza dicha etiqueta, pues, como puedes apreciar, el código fuente pasa a ser más legible, al menos. ¿Cómo puedes hacer uso de la etiqueta [ DELPHI ]? Así:

[ DELPHI ]
// Tu código fuente aquí
[ DELPHI ]

Observa que incluyo espacios dentro de la etiqueta porque de no ser así no podría explicarte su uso. Tampoco estaría demás, aparte de lo dicho, que echaras un vistazo a la guía de estilo de los Foros, fíjate en el apartado "Títulos descriptivos para los mensajes". Por otra parte sé bienvenido.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #4  
Antiguo 03-09-2005
Avatar de droguerman
droguerman droguerman is offline
Miembro
 
Registrado: abr 2005
Ubicación: tierra
Posts: 999
Poder: 20
droguerman Va por buen camino
intenta esto:
Código Delphi [-]
 TFMensajes = procedure(texto: pAnsiChar); stdcall;
y la funcion freeLibrary usala solo cuando estes seguro que no vas a volver a hacer una llamada a loadlibrary de esa DLL sino resultará en una violación de acceso
Responder Con Cita
  #5  
Antiguo 04-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Acceso a DLL, errores al cargar funcion

Hola.

He probado casi todas las opciones stdcall, cdecl, safecall, etc. Sigue sin funcionar cuando intento acceder a la funcion HandleEGDB. No soy un experto en Delphi, siento insistir en el problema. Para aclarar ideas he desarrollado 2 versiones del programa. Una carga la libreria estaticamente y otra la carga dinamicamente. En separados mensajes pongo los codigos de ambas versiones. La unidad comun uTiposEGDB esta en otro mensaje para no cargar demasiado este. Si esta permitido, puedo enviar 2 ficheros zip con todos los ficheros de los proyectos. Ocupan unos 70KB por proyecto, sin los ficheros de las bases de datos que consulta la libreria. Estos se encuentran en CheckerBoard o en KingsRow.

Gracias dec por la modificacion y por la sugerencia. Sin embargo, he consultado la guia de estilo y no he encontrado referencias a la la etiqueta DELPHI. Creo que seria conveniente poner una lista de las etiquetas permitidas. Algo que si que está en la FAQ, pero con la referencia CODE de VB. Ademas, antes de enviar la consulta, investigue si alguien habia hecho alguna referencia a errores de este tipo buscando hilos sobre DLL, pero en los que vi, no habia codigo que pudiese darme una pista para poner el mio bien formateado.

Gracias por la ayuda.

Última edición por aggg63 fecha: 04-09-2005 a las 20:55:47.
Responder Con Cita
  #6  
Antiguo 04-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Unidad estatica

Código Delphi [-]
unit uEGDB;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,StdCtrls;
type
TForm1=class(TForm)
btnIdentificarTF:TButton;
memResultados:TMemo;
procedure btnIdentificarTFClick(Sender:TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1:TForm1;
implementation
uses
uTiposEGDB;
type
TFMensajes = procedure(texto: pAnsiChar); cdecl;
function IdentificarTablaFinales
(directory: pAnsiChar; var db_type: EGDB_TYPE; var max_pieces: Integer)
:integer; stdcall; external 'egdb.dll' name 'egdb_identify';
function AbrirTablaFinales
(bitmap_type: EGDB_BITMAP_TYPE; pieces,cache_mb: Integer;
directory: pAnsiChar; FMensajes: TFMensajes)
:PEGDB_DRIVER; cdecl; external 'egdb.dll' name 'egdb_open';
{$R *.dfm}
procedure FMensaje(texto: pAnsiChar); cdecl;
var
FicheroTexto: TextFile;
begin
AssignFile(FicheroTexto,'FicheroEGDB.txt');
Rewrite(FicheroTexto);
Write(FicheroTexto,texto);
CloseFile(FicheroTexto);
end;
function DescripcionTipoEGDB(tipo: EGDB_TYPE):string;
begin
case tipo of
EGDB_KINGSROW_WLD: result:='KingsRow WLD';
EGDB_KINGSROW_MTC: result:='KingsRow MTC';
EGDB_CAKE_WLD: result:='Cake WLD';
EGDB_CHINOOK_WLD: result:='Chinook WLD';
EGDB_KINGSROW32_WLD: result:='KingsRow32 WLD';
EGDB_KINGSROW32_MTC: result:='KingsRow32 MTC';
EGDB_CHINOOK_ITALIAN_WLD: result:='Chinook Italian WLD ';
EGDB_KINGSROW32_ITALIAN_WLD: result:='KingsRow32 Italian WLD';
EGDB_KINGSROW32_ITALIAN_MTC: result:='KingsRow32 Italian MTC';
end;
end;
procedure TForm1.btnIdentificarTFClick(Sender:TObject);
var
directorio: pAnsiChar;
TipoEGDB: EGDB_TYPE;
HandleEGDB: PEGDB_DRIVER;
IdentificacionCorrecta,piezas: Integer;
FMensajes: TFMensajes;
begin
directorio:='c:\damas\damas\egdb1\cake';
IdentificacionCorrecta:=IdentificarTablaFinales(directorio,TipoEGDB,piezas);
if IdentificacionCorrecta=0 then begin
memResultados.Lines.Add('Tipo EGDB: '+DescripcionTipoEGDB(TipoEGDB));
memResultados.Lines.Add('Piezas: '+inttostr(piezas));
end;
HandleEGDB:=AbrirTablaFinales(EGDB_NORMAL,piezas,300,directorio,FMensajes);
end;
end.
Responder Con Cita
  #7  
Antiguo 04-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Unidad dinamica

Código Delphi [-]
unit uEGDB;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
Dialogs,StdCtrls;
type
TForm1=class(TForm)
btnIdentificarTF:TButton;
memResultados:TMemo;
procedure btnIdentificarTFClick(Sender:TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1:TForm1;
implementation
uses
uTiposEGDB;
type
TFMensajes = procedure(texto: pAnsiChar); cdecl;
var
HandleDLL: THandle;
IdentificarTablaFinales: function(directory: pAnsiChar;
var db_type: EGDB_TYPE;
var max_pieces: Integer)
:integer; stdcall;
AbrirTablaFinales: function(bitmap_type: EGDB_BITMAP_TYPE;
pieces,cache_mb: Integer;
directory: pAnsiChar;
FMensajes: TFMensajes)
:PEGDB_DRIVER; cdecl;
{$R *.dfm}
procedure FMensaje(texto: pAnsiChar); cdecl;
var
FicheroTexto: TextFile;
begin
AssignFile(FicheroTexto,'FicheroEGDB.txt');
Rewrite(FicheroTexto);
Write(FicheroTexto,texto);
CloseFile(FicheroTexto);
end;
function CargarFuncionDLL(FicheroDLL: String; var HandleDLL: THandle;
Nombre: String; Indice: Integer=-1):Pointer;
begin
Result:=nil;
HandleDLL:=LoadLibrary(pAnsiChar(FicheroDLL));
If HandleDLL=0 then Exit;
If Indice<0 then
Result:=GetProcAddress(HandleDLL,pAnsiChar(Nombre))
else
Result:=GetProcAddress(HandleDLL,pAnsiChar(Indice));
end;
function DescripcionTipoEGDB(tipo: EGDB_TYPE):string;
begin
case tipo of
EGDB_KINGSROW_WLD: result:='KingsRow WLD';
EGDB_KINGSROW_MTC: result:='KingsRow MTC';
EGDB_CAKE_WLD: result:='Cake WLD';
EGDB_CHINOOK_WLD: result:='Chinook WLD';
EGDB_KINGSROW32_WLD: result:='KingsRow32 WLD';
EGDB_KINGSROW32_MTC: result:='KingsRow32 MTC';
EGDB_CHINOOK_ITALIAN_WLD: result:='Chinook Italian WLD ';
EGDB_KINGSROW32_ITALIAN_WLD: result:='KingsRow32 Italian WLD';
EGDB_KINGSROW32_ITALIAN_MTC: result:='KingsRow32 Italian MTC';
end;
end;
procedure TForm1.btnIdentificarTFClick(Sender:TObject);
var
directorio: pAnsiChar;
TipoEGDB: EGDB_TYPE;
HandleEGDB: PEGDB_DRIVER;
IdentificacionCorrecta,piezas: Integer;
FMensajes: TFMensajes;
begin
IdentificarTablaFinales:=CargarFuncionDLL('egdb.dll',HandleDLL,'egdb_identify');
if assigned(IdentificarTablaFinales) then begin
directorio:='c:\damas\damas\egdb2\cake';
IdentificacionCorrecta:=IdentificarTablaFinales(directorio,TipoEGDB,piezas);
end;
if IdentificacionCorrecta=0 then begin
memResultados.Lines.Add('Tipo EGDB: '+DescripcionTipoEGDB(TipoEGDB));
memResultados.Lines.Add('Piezas: '+inttostr(piezas));
end;
AbrirTablaFinales:=CargarFuncionDLL('egdb.dll',HandleDLL,'egdb_open');
if assigned(AbrirTablaFinales) then
HandleEGDB:=AbrirTablaFinales(EGDB_NORMAL,piezas,30,directorio,FMensajes);
FreeLibrary(HandleDLL);
end;
end.

Última edición por aggg63 fecha: 04-09-2005 a las 20:57:23.
Responder Con Cita
  #8  
Antiguo 04-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Unida comun

Código Delphi [-]
unit uTiposEGDB;
interface

const
 // Color definitions
    EGDB_BLACK = 0;
    EGDB_WHITE = 1;
   // Values returned by handle->lookup()
    EGDB_UNKNOWN = 0; // value not in the database
    EGDB_WIN = 1; EGDB_LOSS = 2; EGDB_DRAW = 3;
    EGDB_NOT_IN_CACHE = 4; // conditional lookup and position not in cache
   // MTC macros
 MTC_THRESHOLD = 10;
    MTC_LESS_THAN_THRESHOLD = 1;
    MTC_UNKNOWN = 0;

type
 // Tipos de tablas de finales
 EGDB_TYPE = (
  EGDB_KINGSROW_WLD=0, EGDB_KINGSROW_MTC,
        EGDB_CAKE_WLD, EGDB_CHINOOK_WLD,
        EGDB_KINGSROW32_WLD, EGDB_KINGSROW32_MTC,
        EGDB_CHINOOK_ITALIAN_WLD,EGDB_KINGSROW32_ITALIAN_WLD,
        EGDB_KINGSROW32_ITALIAN_MTC);
 // for database lookup stats
 EGDB_STATS = record
     lru_cache_hits,lru_cache_loads,autoload_hits,
        db_requests,db_returns,db_not_present_requests: cardinal;
 end;
 EGDB_BITMAP_TYPE = (EGDB_NORMAL=0, EGDB_ROW_REVERSED);
 // This is KingsRow's definition of a checkers position.
 EGDB_NORMAL_BITMAP = record
     black,white,king: cardinal;
    end;
 // This is Cake's definition of a board position.
 EGDB_ROW_REVERSED_BITMAP = record
     black_man,black_king,white_man,white_king: cardinal;
    end;
    EGDB_BITMAP = record
     case integer of
         0: (normal: EGDB_NORMAL_BITMAP);
            1: (row_reversed: EGDB_ROW_REVERSED_BITMAP);
        end;
 PEGDB_BITMAP = ^EGDB_BITMAP;
    PEGDB_STATS = ^EGDB_STATS;
   // The driver handle type
   PEGDB_driver = ^TEGDB_driver;
    TEGDB_driver = record
     lookup: function (handle: PEGDB_driver; position: PEGDB_BITMAP;
                          color: integer; cl: integer): longint; cdecl; {stdcall;}
        reset_stats: procedure (handle: PEGDB_driver); cdecl;
        get_stats: function (handle: PEGDB_driver): PEGDB_STATS; cdecl;
        verify: function (handle: PEGDB_driver): integer; cdecl;
        close: function (handle: PEGDB_driver): integer; cdecl;
        internal_data: pointer;
    end;

implementation

end.
Responder Con Cita
  #9  
Antiguo 05-09-2005
Avatar de jmariano
jmariano jmariano is offline
Miembro
 
Registrado: jul 2005
Posts: 376
Poder: 19
jmariano Va por buen camino
Saludos aggg63!

Te aconsejo identar un poco el código para que sea más legible y, sobretodo, que, en vez de crear varios hilos, comprimas las fuentes que quieres mostrar en un .zip y lo adjuntes al hilo, porque sino se hace muy dificil analizar tu problema. (Para poder adjuntar un archivo al hilo, pulsa sobre el boton "Responder" y busca en la parte inferior el bóton "Administrar Adjuntos", el cual te permitirá subir un archivo al foro).

Chao!

Última edición por jmariano fecha: 05-09-2005 a las 01:43:45.
Responder Con Cita
  #10  
Antiguo 05-09-2005
Avatar de droguerman
droguerman droguerman is offline
Miembro
 
Registrado: abr 2005
Ubicación: tierra
Posts: 999
Poder: 20
droguerman Va por buen camino
bueno te aconsejo leer esta pagina con la cual aprendí sobre las DLL con ejemplo y todo, puede que por ahi te falte una @:http://www.delphi-central.com/dynamicdll.aspx

ahora con las DLL hay problemas que a veces son dificiles de entender hace poco hice una DLL que cargaba un TForm, cuando la llamaba desde mi aplicacion desde el explorer corria sin problemas, pero cuando otra q usaba winexec para llamar a mi aplicacion simplemente colgaba la maquina, asi que tuve q pasar a shellExecute, prueba con crearte una app pequeña y trata de ejecutar la llamada
Responder Con Cita
  #11  
Antiguo 08-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Unidades para acceder a la DLL

Gracias droguerman por la sugerencia pero sigue sin funcionar. He recibido confirmacion del autor de la dll que todas las llamadas son cdecl y no stdcall. Sin embargo, he probado combinaciones y no funciona. Le he pedido que haga una dll sin la funcion que devuelve un menaje a ver si asi aislamos el problema. Estoy a la espera. De momento envio un fichero zip con 3 unidades que llaman a la dll de 3 maneras distintas, si alguien puede echarle un vistazo, estaria agradecido.
Archivos Adjuntos
Tipo de Archivo: zip egdb.zip (4,1 KB, 29 visitas)
Responder Con Cita
  #12  
Antiguo 08-09-2005
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
Este hilo es muy largo y quizá me he saltado algo pero creo que hasta ahora no has mencionado cuál es el error que te dá excepto la mención original de "no me carga bien las funciones que exporta la DLL" pero supongo que sí las carga ya que verificas el resultado de GetProcAddress.

Además del convenio de llamada, ¿has revisado la forma en que declaras el encabezado?

Es decir, en

Código Delphi [-]
AbrirTablaFinales: function(bitmap_type: EGDB_BITMAP_TYPE;
pieces,cache_mb: Integer;
directory: pAnsiChar;
FMensajes: TFMensajes)
:PEGDB_DRIVER; cdecl;

¿estás seguro que el último parámetro debe ser así? Según la declaración de TFMensajes:

Código Delphi [-]
type
  TFMensajes = procedure(texto: pAnsiChar); cdecl;

infiero que el último parámetro es una función pero a juzgar por otras declaraciones en Delphi de la API de Windows, cuando un parámetro es una función, lo declaran como LongInt y luego hacen un moldeo para acceder a la función, es decir, que en ese tipo de parámetros reciben la dirección (LongInt) de la función.

Bueno, a lo mejor no tiene nada que ver pero igual te da una idea.

// Saludos
Responder Con Cita
  #13  
Antiguo 08-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Cambiar funcion por direccion

Hola.

El error que obtengo es:
"Access violation at address 00000000. Write of address 00000000" al ejecutar la linea:

Código:
HandleEGDB:=AbrirTablaFinalesEGDB_NORMAL,piezas,30,directorio,FMensajes);
Efectivamente, el ultimo parametro es una funcion a la que se le pasa un mensaje (pAnsiChar). Por lo que comentas y lo poco que se de Delphi avanzado, ¿estas sugiriendo que en vez de usar la funcion, use su direccion? Y ademas ¿moldeo=casting,typecast? ¿Y como llamo a una funcion sabiendo su direccion? ¿Podrias indicarme alguna API de ejemplo para echarle un vistazo?

Intentare hacer unas pruebas y averiguar algo mas.

Gracias por la sugerencia.

Cita:
Empezado por roman
Este hilo es muy largo y quizá me he saltado algo pero creo que hasta ahora no has mencionado cuál es el error que te dá excepto la mención original de "no me carga bien las funciones que exporta la DLL" pero supongo que sí las carga ya que verificas el resultado de GetProcAddress.

Además del convenio de llamada, ¿has revisado la forma en que declaras el encabezado?

Es decir, en

Código Delphi [-]
AbrirTablaFinales: function(bitmap_type: EGDB_BITMAP_TYPE;
pieces,cache_mb: Integer;
directory: pAnsiChar;
FMensajes: TFMensajes)
:PEGDB_DRIVER; cdecl;

¿estás seguro que el último parámetro debe ser así? Según la declaración de TFMensajes:

Código Delphi [-]
type
TFMensajes = procedure(texto: pAnsiChar); cdecl;

infiero que el último parámetro es una función pero a juzgar por otras declaraciones en Delphi de la API de Windows, cuando un parámetro es una función, lo declaran como LongInt y luego hacen un moldeo para acceder a la función, es decir, que en ese tipo de parámetros reciben la dirección (LongInt) de la función.

Bueno, a lo mejor no tiene nada que ver pero igual te da una idea.

// Saludos
Responder Con Cita
  #14  
Antiguo 08-09-2005
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
Dime una cosa; este parámetro del que hablamos, ¿es para recibir una función o para mandar una función? Es decir, ¿no será que egdb_open espera una función ya hecha? Porque de ser así, tendrías no sólo que declararla sino implementarla:


Código Delphi [-]
procedure Mensajes(texto: pAnsiChar); cdecl;
begin
  bla, bla, bla
end;

y al llamar a egdb_open pasas @Mensajes (arroba incluida) como parámetro.

// Saludos
Responder Con Cita
  #15  
Antiguo 09-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Hola.
La funcion esta implementada y ya probe tambien la opcion de pasar la direccion como @FMensaje, aunque en el codigo expuesto en un mensaje no aparezca. Da el mismo error.

Código:
procedure FMensaje(texto: pAnsiChar); cdecl;
var
FicheroTexto: TextFile;
begin
	 AssignFile(FicheroTexto,'FicheroEGDB.txt');
	 Rewrite(FicheroTexto);
	  Write(FicheroTexto,texto);
	 CloseFile(FicheroTexto);
end;
Responder Con Cita
  #16  
Antiguo 09-09-2005
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
Cita:
Empezado por aggg63
Da el mismo error
Sí, pero ¿cambiaste la declaración de egdb_open para que el último parámetro sea LongInt?

// Saludos
Responder Con Cita
  #17  
Antiguo 10-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Cambio de tipos

Supongo que te refieres a que cambie la definicion de la funcion

Código:
AbrirTablaFinales:function(bitmap_type: EGDB_BITMAP_TYPE;
pieces,cache_mb: Integer;
directory: pAnsiChar;
FMensajes: TFMensajes)
:PEGDB_DRIVER; cdecl;
por

Código:
AbrirTablaFinales:function(bitmap_type: EGDB_BITMAP_TYPE;
pieces,cache_mb: Integer;
directory: pAnsiChar;
direccion: longint):
PEGDB_DRIVER; cdecl;
Pues si, he cambiado la definicion y he probado los tipos integer, longint, longword y cardinal. Tambien he probado a poner un tipo pointer. En este caso me da unas direcciones de memoria diferentes en el error: "Access violation at address 100052D2 in module 'egdb.dll'. Write of address 00019DF0".


Gracias por la ayuda.
Responder Con Cita
  #18  
Antiguo 11-09-2005
aggg63 aggg63 is offline
Miembro
 
Registrado: sep 2005
Posts: 31
Poder: 0
aggg63 Va por buen camino
Solucionado el problema pero ...

Gracias a todos por los consejos, pero mi supina ignorancia en temas avanzados de Delphi me han llevado a cometer un error de principiante . El problema se ha solucionado SIMPLEMENTE asignando la funcion tipo TFMensajes a una variable que habia declarado en el procedimiento. Ahora funciona perfectamente ... si no fuera por que al terminar el procedimiento se genera otra excepcion: "Access violation at 0x004308D8. Read of address 0x00000000". He probado varias cosas, pero no funciona ninguna. Supongo que es algun puntero que no libero o que hace falta algo mas para descargar la dll de la memoria.

Código Delphi [-]
unit uEGDB;
interface
uses
    Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
    Dialogs,StdCtrls;
type
    TForm1=class(TForm)
        btnIdentificarTF:TButton;
        memResultados:TMemo;
        procedure btnIdentificarTFClick(Sender:TObject);
    private
        { Private declarations }
    public
        { Public declarations }
    end;
var
    Form1:TForm1;
implementation
uses
    uTiposEGDB;
type
    TFMensajes = procedure(texto: pAnsiChar); cdecl;
var
   HandleDLL: THandle;
   IdentificarTablaFinales: function(directory: pAnsiChar;
              var db_type: EGDB_TYPE; var max_pieces: Integer)
              :integer; stdcall;
   AbrirTablaFinales: function(bitmap_type: EGDB_BITMAP_TYPE;
           pieces,cache_mb: Integer; directory: pAnsiChar;
           FMensajes: TFMensajes):PEGDB_DRIVER; cdecl;
    FicheroTexto: TextFile;
{$R *.dfm}
procedure FMensaje(texto: pAnsiChar); cdecl;
begin
    Append(FicheroTexto);
    Write(FicheroTexto,texto);
    CloseFile(FicheroTexto);
end;
function DescripcionTipoEGDB(tipo: EGDB_TYPE): string;
begin
 case tipo of
        EGDB_KINGSROW_WLD: result:='KingsRow WLD';
        EGDB_KINGSROW_MTC: result:='KingsRow MTC';
        EGDB_CAKE_WLD: result:='Cake WLD';
        EGDB_CHINOOK_WLD: result:='Chinook WLD';
        EGDB_KINGSROW32_WLD: result:='KingsRow32 WLD';
        EGDB_KINGSROW32_MTC: result:='KingsRow32 MTC';
        EGDB_CHINOOK_ITALIAN_WLD: result:='Chinook Italian WLD ';
        EGDB_KINGSROW32_ITALIAN_WLD: result:='KingsRow32 Italian WLD';
        EGDB_KINGSROW32_ITALIAN_MTC: result:='KingsRow32 Italian MTC';
    end;
end;
procedure TForm1.btnIdentificarTFClick(Sender:TObject);
var
    directorio: pAnsiChar;
    TipoEGDB: EGDB_TYPE;
    HandleEGDB: PEGDB_DRIVER;
    IdentificacionCorrecta,piezas: Integer;
    Funcion: TFMensajes;
    cerrar: Integer;
    liberar: boolean;
begin
   HandleDLL:=LoadLibrary('egdb.dll');
   if HandleDLL>32 then begin
     @IdentificarTablaFinales:=GetProcAddress(HandleDLL,'egdb_identify');
     @AbrirTablaFinales:=GetProcAddress(HandleDLL,'egdb_open');
   end;
   if assigned(IdentificarTablaFinales) then begin
     directorio:='c:\damas\damas\egdb3\cake';
     IdentificacionCorrecta:=IdentificarTablaFinales(directorio,TipoEGDB,piezas);
   end;
   if IdentificacionCorrecta=0 then begin
     memResultados.Lines.Add('Tipo EGDB:   '+DescripcionTipoEGDB(TipoEGDB));
     memResultados.Lines.Add('Piezas:      '+inttostr(piezas));
   end;
   if assigned(AbrirTablaFinales) then begin
        Funcion:=FMensaje; // SOLUCION DEL PROBLEMA
        HandleEGDB:=AbrirTablaFinales(EGDB_NORMAL,piezas,30,directorio,Funcion);
    end;
  @funcion:=nil;
  @IdentificarTablaFinales:=nil;
  @AbrirTablaFinales:=nil;
  cerrar:=HandleEGDB.close(HandleEGDB);
  if cerrar=0 then 
     memResultados.Lines.Add('EGDB cerrada:      '+inttostr(cerrar));
  HandleEGDB:=nil;
  freeandnil(HandleEGDB);
  liberar:=FreeLibrary(HandleDLL);
  if liberar then
     memResultados.Lines.Add('DLLEGDB liberada:      '+inttostr(cerrar));
end;
initialization
    AssignFile(FicheroTexto,'FicheroEGDB.txt');
    Rewrite(FicheroTexto);
finalization
    //FreeLibrary(HandleDLL);
end.
Responder Con Cita
  #19  
Antiguo 18-02-2013
bohemio87x bohemio87x is offline
Registrado
NULL
 
Registrado: feb 2013
Posts: 1
Poder: 0
bohemio87x Va por buen camino
Necesito ese motor de damas esp...

hola viejo, a estas alturas que vengo a dar con este tema, supongo que solucionaste el problema y terminaste de desarrolar el motor de damas españolas que empezaste, sabes, tengo tiempo buscando un motor que juege la variante española de damas y hasta aqui no lo eh conseguido, quisiera tu ayuda. Ojala pudieras poporcionarme ese motro o darme el link de donde pueda descargar uno...
Responder Con Cita
  #20  
Antiguo 18-02-2013
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración
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 11:57:29.


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