PDA

Ver la Versión Completa : problema con creacion de DLL


acertij022
20-11-2006, 14:11:48
Hola delphiano hace una semana pedi ayuda para encriptar string en triple-DES y me recomendaron el componente DCPcrypt http://www.cityinthesky.co.uk/cryptography.html
Bueno todo funciona perfecto pero ahora necesito encapsularlo en una DLL para poder usarlo en otros lenguajes. Al intentar levantar la DLL desde Delphi me sale un error (Invalid pointer operation).
El codigo de la DLL es el siguiente:

library des;

uses
SysUtils,
Classes,
DCPcrypt2, DCPblockciphers, DCPdes, DCPsha1;

{$R *.res}
function TripleDes(dato,contrasenia:string;accion:boolean):string; stdcall; overload;
var
Cipher: TDCP_3des;
begin
Cipher:= TDCP_3des.Create(nil);//(Self);
Cipher.InitStr(contrasenia,TDCP_sha1); // initialize the cipher with a hash of the passphrase
if accion=true then Result:= Cipher.EncryptString(dato)
else Result:= Cipher.DecryptString(dato);
Cipher.Burn;
Cipher.Free;
end;

Exports TripleDes(dato,contrasenia:string;accion:boolean);

begin
end.

y el codigo en delphi para levantar la DLL es:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
GroupBox1: TGroupBox;
Memo1: TMemo;
GroupBox2: TGroupBox;
Memo2: TMemo;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function TripleDes(dato,contrasenia:string;accion:boolean):string; stdcall; external 'DES.DLL';

procedure TForm1.Button1Click(Sender: TObject);
begin
memo2.Text := TripleDes(memo1.Text,edit1.text,true);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
memo2.Text := TripleDes(memo1.Text,edit1.text,false);

end;

end.

supongo que el error es que uso como parametro NIL en vez de SELF al crear el componente pero si colo este ultimo no me compila([Error] des.dpr(13): Undeclared identifier: 'Self').

Espero que alguien me pueda ayudar desde ya muchas gracias :D

tefots
20-11-2006, 16:44:57
Hola

siempres que crees alguna dll , o intentes llamar a alguna funcion que se encuentra en una dll , no puedes usar tipos strings , has de usar pchars.


function TripleDes(dato,contrasenia : pchar;accion:boolean):string; stdcall;

y para llamar a la funcion , puedes forzar a pchar .



procedure TForm1.Button1Click(Sender: TObject);
begin
memo2.Text := TripleDes(pchar(memo1.Text),pchar(edit1.text),true);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
memo2.Text := TripleDes(pchar(memo1.Text),pchar(edit1.text),false);
end;

acertij022
20-11-2006, 16:59:26
Intente lo que me comentaste usar Pchar en vez de string y me sigue tirando error pero esta ves me tira Acces violation at address 00401C66 in module 'Project1.exe'. Write of address 003809D4

¿que podra ser?

avmm2004
20-11-2006, 19:59:52
Utiliza shortstring en vez de Pchar o strings y no obstante utiliza la unit Sharemem como primera unit de tu dll y de tu programa llamador.
De resto debe de funcionarte bien, por lo menos a mi siguiendo esas reglas no tengo problemas.

acertij022
20-11-2006, 21:17:16
gracias por el dato avmm2004 pero ahun me sigue tirando error de memoria intentare probarlo en otra pc para descartar.

acertij022
21-11-2006, 21:27:53
hola de nuevo realice pruebas en otra pc e incluso desintale el windows xp y coloque windows 2000 y sigue el problema.

Para hacer mas simple cree una dll:

library Project2;

uses
SysUtils,
Classes;

{$R *.res}

function sumar(a,b:shortstring):string;stdcall;
begin
Result:= IntToSTr(StrToInt(a)+StrToInt(b));
end;

Exports sumar;
begin
end.


y una aplicacion que suma usando la DLL:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
function sumar(a,b:shortstring):string; stdcall; external 'Project2.dll';

procedure TForm1.Button1Click(Sender: TObject);
begin
label1.Caption := sumar(edit1.Text,edit2.Text);
end;

end.


pero al cliquear en el botón realiza la suma pero coloca un cartel de error:
Invalid pointer operation

Por lo visto hay algo basico que hago mal :confused:
Espero que alguien me tire un cable por favor

avmm2004
21-11-2006, 22:48:23
El parámetro que devuleve la función debe ser no string sino shortstring y te repito, utiliza Sharemem la primera de todas en tu sentencia uses en la dll y el programa llamador. Los problemas te vienen por el uso de string y no shortsring.

Pd: Si lo que quieres es sumar dos numeros pasele integer y devuelve integer.(en el ejemplo, claro) veras que si no utilzas string desaparece el error. Los strings es mejor usarlos como te digo, a mi me funciona bien.

acertij022
22-11-2006, 13:21:29
Muchas gracias avmm2004 y disculpa mi ignorancia habia pasado de alto tambien Sharemem :p

acertij022
23-11-2006, 15:48:29
Hola de nuevo he realizado cambio en mi dll y ya no utilizo mas Sharemem porque mi intencion es usarlo en otros entornos (c#) y según lei para ser compatible con cualquier entorno el dato debe ser PChar ya que el string que usa delphi esta compueto por: cantidad de char + array de char y PChar esta compueto por: array de char + chr(0) que indica el final del string Según dice aquí (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=814709&SiteId=1)

Muchas gracias a todos!!:p