Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Error en DLL (https://www.clubdelphi.com/foros/showthread.php?t=46319)

MON___ 28-07-2007 19:41:08

Error en DLL
 
Tengo una DLL en SYSTEM32 y en ella la siguiente función:

{ Abre una ventana con un objeto TEDIT para un proceso de búsqueda }
function buscarValor(
var devuelto : string; {guarda la cadena de búsqueda}
caracteres : integer; {máximo de caracteres para el objeto TEDIT}
mayusculas : boolean {si sólo se admite la edición en mayúsculas}
):boolean; stdcall; export; {TRUE: si se ha aceptada y escrito texto en TEDI}

Ésta es la rutina escrita en la DLL

FBuscar := TFBuscar.create(nil);
try
with FBuscar do
begin
edit1.maxLength := caracteres;
if mayusculas then edit1.charCase := ecUpperCase else edit1.charCase := ecNormal;
result := showModal = mrok;
if result then devuelto := edit1.text;
end;
finally
FBuscar.free;
end;


En el FORM de la aplicación que hace la llamada:

type
TLlamarDLL = function (var s : string; x : integer; m : boolean) : boolean;
var
DLL : HWND;
LlamarDLL : TLLamarDLL;
s : string;
begin
DLL := loadLibray('MONLIB.DLL');
if DLL > 0 then
try
@LlamarDLL := getProcAddress(DLL, 'buscarValor');
if @LlamarDLL <> nil then
if llamarDLL(s, 50, True) then
edit1.text := s;
finally
FreeLibrary(DLL);
end;
end;

Pues bien. Si el resultado es FALSE (he pulsado en la ventana que se abre con la función el botón CANCELAR) no me da error. En cambio, si el resultado de la función es TRUE (he pulsado ACEPTAR y además he escrito texto) se me da el error: EAccessViolation

¿Dónde puede estar el error?

cHackAll 30-07-2007 10:19:17

Bueno, le dí un vistazo rápido al código y me parece que hay dos posibles fallas, sin embargo me inclino a una de ellas… prueba el siguiente código y no dejes de contarnos como te va:

Código Delphi [-]
…
 
result := showModal = mrok;
if result then
 begin
  SetLength(Str, Length(Edit1.Text));
  Move(Edit1.Text[1], Str[1], Length(Str));
 end;

...

MON___ 30-07-2007 14:26:09

Gracias, "chackAll" por la respuesta. Desgraciadamente me sigue dando el mismo error (EAccessViolation); ¿cuál es la segunda posibilidad? :rolleyes:
Gracias de nuevo por tu respuesta.

cHackAll 30-07-2007 16:35:04

Vaya, en ves de string; declara ShortString o PChar en la librería y en el proyecto que lo llama (en el proyecto original)...

Cita:

Empezado por Delphi
To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters.



Si ésto no dá aconsejo subas parte del cógido (mínimo funcional) para corregirlo.

MON___ 30-07-2007 16:46:11

Gracias de nuevo, CheckAll. No creo que sea un problema de tipos (string, pchar).
He depurado paso a paso el código y he inspecionado las variables. El error (EAccessViolation) se produce en "FreeLibrary"

procedure TForm1.SpeedButton1Click(Sender: TObject);
type
TLlamarDLL = function(var s : string; x : integer; si : boolean): boolean;
var
buffer : string;
DLL : HWND;
LlamarDLL : TLlamarDLL;
begin
buffer := '';
DLL := LoadLibrary('monlib.dll');
try
@LlamarDLL := GetProcAddress(DLL, 'buscarValor');
if @LlamarDLL <> nil then
if llamarDLL(buffer, 30, false) then
edit1.text := buffer;
finally
FreeLibrary(DLL);
end;

end;

egostar 30-07-2007 17:43:12

Prueba cambiando el tipo de la variable DLL.

DLL : HWND; -----> DLL : THandle;

Salud OS.

MON___ 30-07-2007 17:48:12

Gracias de nuevo. Lo he hecho de las dos formas (THandle / HWND); ahora he estado probando con la directiva "stdcall" y sin ella, pero sigue dándome error.

roman 30-07-2007 18:25:23

¿Hiciste lo que te comentó cHackAll respecto del tipo de datos string? No es opcional. Si usas strings sin recurrir a BORLNDMM.DLL, la dll va a fallar sí o sí. Además, aunque no aseguro que sea la causa, un string no es sino un apuntador cuya memoria se maneja dinámicamente, y como tal, no sería de extrañar que los errores sólo se manifiesten al intentar liberar recursos, como lo hace FreeLibrary.

// Saludos

MON___ 30-07-2007 19:01:28

¡Gracias a los dos! ¡Tenéis razón! He cambiado STRING por PCHAR y no se produce el error al liberar la librería (FreeLibrary).:p:p:p

Black_Ocean 24-06-2008 01:46:03

Este error es común, ya que las DLL's no manejan conceptos de Strings como en Delphi, sino que manejan Punteros a caracteres. En Delphi no te arrojará un error de compilación al declarar un string dentro de la DLL, sino que cuando llames a esa función de la DLL generará una excepción. Recuerden que una DLL no es una librería compilada en lenguaje Delphi (aunque la hayas escrito y compilado en Delphi), sino más bien se compila igual que una biblioteca común de Windows para que aplicaciones externas puedan interpretarlas, independiente del lenguaje en el cual hayan sido escritas esas aplicaciones, Exceptuando las librerías que son .NET, pero, esa es otra historia =).

Saludos.


La franja horaria es GMT +2. Ahora son las 05:56:22.

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