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 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
  #2  
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
  #3  
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
  #4  
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
  #5  
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
  #6  
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
  #7  
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
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:48:17.


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