Ir al contenido


Foto

[RESUELTO] Creando una DLL


  • Por favor identifícate para responder
11 respuestas en este tema

#1 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 29 julio 2010 - 08:47

Estoy tratando de colocar una función en una DLL, he leído y buscado y según parece la forma es la siguiente:

Asi se crea la DLL:



delphi
  1. library dlEncrip;
  2.  
  3.  
  4. uses
  5.   ShareMem,
  6.   SysUtils,
  7.   Classes;
  8.  
  9. {$R *.res}
  10.  
  11. //Desencripta la Clave
  12. function Desencriptar(cCadena: string): String; stdcall;
  13. var
  14.   arClave: array[0..53] of Char;
  15.   S, S1: string;
  16.   nIndice, n, nLCadena: integer;
  17. begin
  18.   //La Carga a la matriz
  19.  
  20. **** codigo de la funcion ****
  21.  
  22.   Result := S;
  23. end;
  24.  
  25. exports Desencriptar;
  26.  
  27. begin
  28.  
  29.  
  30. end.



Así hago la llamada desde el programa:



delphi
  1. function Desencriptar(cCadena: String): String; stdcall; external 'dlEncrip.dll';



Pero me lanza un

---------------------------
Debugger Exception Notification
---------------------------
Project dllprobando.exe raised exception class EAccessViolation with message 'Access violation at address 00392144 in module 'dlEncrip.dll'. Read of address 00120048'. Process stopped. Use Step or Run to continue.
---------------------------
OK  Help 
---------------------------


Justo en esta linea:



delphi
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. begin
  3.   Edit2.Text := Desencriptar(Edit1.Text);
  4. end;



La DLL esta en la misma carpeta que el ejecutable, me estoy saltando algun paso?
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 29 julio 2010 - 08:51

No debería de ser así ?



delphi
  1. library dlEncrip;
  2.  
  3. uses
  4.   ShareMem,
  5.   SysUtils,
  6.   Classes;
  7.  
  8. {$R *.res}
  9.  
  10. //Desencripta la Clave
  11. function Desencriptar(cCadena: string): String; export;
  12. var
  13.   arClave: array[0..53] of Char;
  14.   S, S1: string;
  15.   nIndice, n, nLCadena: integer;
  16. begin
  17.   //La Carga a la matriz
  18.  
  19. **** codigo de la funcion ****
  20.  
  21.   Result := S;
  22. end;
  23.  
  24. exports Desencriptar;
  25.  
  26. begin
  27.  
  28. end.



Salud OS
  • 0

#3 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 29 julio 2010 - 09:00

Acabo de probar y nada...  :p <:o)
  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 29 julio 2010 - 09:02

Acabo de probar y nada...  :p <:o)


Ah caramba!!!!, deja hacer una prueba.

Salud OS
  • 0

#5 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 29 julio 2010 - 09:08


Acabo de probar y nada...  :p <:o)


Ah caramba!!!!, deja hacer una prueba.

Salud OS



Si la prueba es de licores me avisas jejeje
  • 0

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 29 julio 2010 - 09:14

jejeje, cabron

Pues a menos que sea algo dentro del código de la función de tu DLL no veo porque falla, a mi me funciona bien todo, hasta el cerebro :D :D :D

Te adjunto el código y los binarios de mi prueba del añejo :p

Salud OS

Archivos adjuntos


  • 0

#7 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 29 julio 2010 - 09:42

Estoy haciendo una depuracion y ya veo que hay un problema con los valores que recibe:



delphi
  1. cCadena := #0#0#0#0'l÷'#$12#0'ÖùB'#0'xBµ'#0'Õ€B'#0'¨÷'#$12#0'ɁB'#0'xBµ'#0';øB'#0'¨÷'#$12#0'¨÷'#$12#0'xBµ'#0'Þ'#7#$B#0#0#0#0#0' '#0#0#0'pö'#$12#0'Ø™:~'#$A'€'#0#0'üö'#$12#0'¢[:~'#$A'€'#0#0'Þ'#7#$B#0'üÿÿÿ'#0#0#0#0#0#0#0#0'„÷'#$12#0#$D'S:~'#1#0#0#0'˜uïw @ów;Ì'#0#0'6°;~‚°;~è„s'#0#$15#2#0#0#0#0#0#0#0#0#0#0#1#0#0#0'6°;~ðö'#$12#0'4‡9~Þ'#7#$B#0#$15#2#0#0#0#0#0#0#0#0#0#0'6°;~Í«ºÜ'#0#0#0#0',÷'#$12#0'6°;~X÷'#$12#0'Ù‹9~'#0'àýX÷'#$12#0' '#0#0#0'X÷'#$12#0'øëý'#0#0#0#0'8÷'#


  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 29 julio 2010 - 09:51

Entonces tu problema está en el código de la función de la DLL.

Salud OS
  • 0

#9 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 29 julio 2010 - 12:55

¿Supongo que también estas añadiendo ShareMem a las uses del proyecto y no solo en la dll?  ^o|

ShareMem should always be the first unit listed in any program or library uses clause where it occurs


Ademas ese stdcall tampoco me gusta nada  :p , si realmente quieres algo "estándar" deberias de usar punteros (PChar) y no Strings.
  • 0

#10 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 29 julio 2010 - 01:24

Eso era lo que faltaba el ShareMem en el proyecto, si trabajo con pChar evito la necesidad de esa libreria?
  • 0

#11 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 29 julio 2010 - 02:26

Pues ya lo dice la ayuda de delphi:

On Win32, if a DLL exports routines that pass long strings or dynamic arrays as parameters or function results (whether directly or nested in records or objects), then the DLL and its client applications (or DLLs) must all use the ShareMem unit. The same is true if one application or DLL allocates memory with New or GetMem which is deallocated by a call to Dispose or FreeMem in another module.


Es decir, si no se pasan como parámetros strings o arrays dinámicos, y ademas cada modulo gestiona "su memoria" no hace falta usar ShareMem.

Y aquí un ejemplo de regalo:


delphi
  1. library Prueba;
  2. uses
  3.   SysUtils,
  4.   Classes;
  5.  
  6. {$R *.res}
  7.  
  8. function Test(Src, Dst: PChar; Count: PInteger): Integer; stdcall;
  9. var
  10.   Str: String;
  11. begin
  12.   Str:= String(Src);
  13.   // Lo que quieras hacer con la cadena
  14.   Str:= Str + Str + Str;
  15.   if Length(Str) + 1 <= Count^ then
  16.   begin
  17.     StrCopy(Dst,PChar(Str));
  18.     Result:= Length(Str);
  19.   end else
  20.   begin
  21.     Result:= -1;
  22.     Count^:= Length(Str) + 1;
  23.   end;
  24. end;
  25.  
  26. exports Test;
  27.  
  28. begin
  29. end.



A la función se le pasa como parámetros un puntero a la cadena de origen, un puntero al resultado y un integer con el tamaño máximo (incluido el cero final) que puede tener el resultado. Si todo va bien la función devuelve el tamaño del resultado, pero si no tiene espacio suficiente devuelve -1 y el tamaño necesario lo guarda en el parámetro Count. Muchas funciones de la API funcionan así, no es nada nuevo

Un ejemplito:


delphi
  1. function Test(Src, Dst: PChar; Count: PInteger): Integer; stdcall;
  2.   external 'Prueba.dll';
  3.  
  4. function TestStr(Str: String): String;
  5. var
  6.   i: Integer;
  7. begin
  8.   Result:= EmptyStr;
  9.   i:= 0;
  10.   if Test(PChar(Str),nil,@i)= -1 then
  11.   begin
  12.     SetLength(Result,i);
  13.     if Test(PChar(Str),PChar(Result),@i) < 0 then
  14.       Result:= EmptyStr
  15.     else
  16.       SetLength(Result,StrLen(PChar(Result)));
  17.   end;
  18. end;
  19.  
  20.  
  21. // Por ejemplo
  22. ShowMessage(TestStr('Hola mundo'));



  • 0

#12 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 29 julio 2010 - 02:34

Ok Muchas gracias amigo, eso era todo doy el tema por resuelto.

Gracias a los dos por la ayuda  <:o) <:o)
  • 0




IP.Board spam blocked by CleanTalk.