DLL文件中的两个接口函数,主要用于加解密操作,函数大致如下:
function encrypt(sYue,sMing:string):pchar;stdcall;
sMi:string;
... ...
Result := Pchar(sMi);
end;function decrypt(sYue,sMi:string):pchar;stdcall;
sMing:string;
... ...
decrypt := pchar(sMing);
end;
下午按lxpbuaa(桂枝香在故国晚秋)朋友所说的,将函数encrypt()和decrypt()的返回类型由string改为pchar,纠正了调用时出现的“Invalid pointer operation”错误,但是在调用decrypt()函数时,会出现返回值错误的情况。
跟踪时发现:调用decrypt(),当sMing='12'时,返回值为' '(一个空格)???问题就出在这!!!
如果函数的返回类型为string的话,调用时会出现非法指针的错误提示,但是返回值不会错,这两个函数如果不写成dll调用,嵌入代码中运行又什么问题都没有,一切正常。
困惑,问题到底出在哪呢???
function encrypt(sYue,sMing:string):pchar;stdcall;
sMi:string;
... ...
Result := Pchar(sMi);
end;function decrypt(sYue,sMi:string):pchar;stdcall;
sMing:string;
... ...
decrypt := pchar(sMing);
end;
下午按lxpbuaa(桂枝香在故国晚秋)朋友所说的,将函数encrypt()和decrypt()的返回类型由string改为pchar,纠正了调用时出现的“Invalid pointer operation”错误,但是在调用decrypt()函数时,会出现返回值错误的情况。
跟踪时发现:调用decrypt(),当sMing='12'时,返回值为' '(一个空格)???问题就出在这!!!
如果函数的返回类型为string的话,调用时会出现非法指针的错误提示,但是返回值不会错,这两个函数如果不写成dll调用,嵌入代码中运行又什么问题都没有,一切正常。
困惑,问题到底出在哪呢???
如果是,那可能你在主程序聲明中漏了 stdcall吧??
你把主程序調用代碼貼出來,建議采用如下形式:
function decrypt(sYue,sMi:pchar; pRet:pchar):boolean;stdcall;
將返回寫在 pRet中!
如果正确, 那第二个函数不应该有问题, 你说呢???
function decrypt(sYue,sMi:pchar; pRet:pchar):boolean;stdcall;
返回值保存在pRet中,调用端需要首先给pRet分配内存。可用:
GetMem————————————————————————————————————
宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
————————————————————————————————————
还有encrypt的返回值在某种情况下也会出错。
pRep 应分配的length 好像是strlen(sMi) div 2 +1
加入sharemem后还是不行,返回值还是有问题。
现在出错的焦点到是确定在返回值上了。关键是:当调用是sYue,sMing,sMi的字符串位数较多时,出错的几率也少。
当sYue,sMing都是2位时,先调用encrypt,然后调用decrypt是绝对会出错的。
另外,我比較忙,沒時間看你的代碼,給你的 email;
我發個例子給你,與你的要求是一樣的,是我以前實現的!!!
谢谢各位了。现将vb的源码和delphi自己整理过的代码附上。
vb----------------------------------------
' PC1 Cipher 128-bit key
' (c) Alexander PUKALL 1991
' Can be use freely even for commercial applications
' Visual Basic 6.0Dim x1a0(9) As Long
Dim cle(17) As Long
Dim x1a2 As LongDim inter As Long, res As Long, ax As Long, bx As Long
Dim cx As Long, dx As Long, si As Long, tmp As Long
Dim i As Long, c As BytePrivate Sub Assemble()
x1a0(0) = ((cle(1) * 256) + cle(2)) Mod 65536
code
inter = res
x1a0(1) = x1a0(0) Xor ((cle(3) * 256) + cle(4))
code
inter = inter Xor res
x1a0(2) = x1a0(1) Xor ((cle(5) * 256) + cle(6))
code
inter = inter Xor res
x1a0(3) = x1a0(2) Xor ((cle(7) * 256) + cle(8))
code
inter = inter Xor res
x1a0(4) = x1a0(3) Xor ((cle(9) * 256) + cle(10))
code
inter = inter Xor res
x1a0(5) = x1a0(4) Xor ((cle(11) * 256) + cle(12))
code
inter = inter Xor res
x1a0(6) = x1a0(5) Xor ((cle(13) * 256) + cle(14))
code
inter = inter Xor res
x1a0(7) = x1a0(6) Xor ((cle(15) * 256) + cle(16))
code
inter = inter Xor res
i = 0
End SubPrivate Sub code()
dx = (x1a2 + i) Mod 65536
ax = x1a0(i)
cx = &H15A
bx = &H4E35
tmp = ax
ax = si
si = tmp
tmp = ax
ax = dx
dx = tmp
If (ax <> 0) Then
ax = (ax * bx) Mod 65536
End If
tmp = ax
ax = cx
cx = tmp
If (ax <> 0) Then
ax = (ax * si) Mod 65536
cx = (ax + cx) Mod 65536
End If
tmp = ax
ax = si
si = tmp
ax = (ax * bx) Mod 65536
dx = (cx + dx) Mod 65536
ax = ax + 1
x1a2 = dx
x1a0(i) = ax
res = ax Xor dx
i = i + 1
End SubPrivate Sub crypt()
Form1.Text3 = ""
si = 0
x1a2 = 0
i = 0
For fois = 1 To 16
cle(fois) = 0
Next fois
champ1 = Form1.Text1
lngchamp1 = Len(champ1)
For fois = 1 To lngchamp1
cle(fois) = Asc(Mid(champ1, fois, 1))
Next fois
champ1 = Form1.Text2
lngchamp1 = Len(champ1)
For fois = 1 To lngchamp1
c = Asc(Mid(champ1, fois, 1))
Assemble
If inter > 65535 Then
inter = inter - 65536
End If
cfc = (((inter / 256) * 256) - (inter Mod 256)) / 256
cfd = inter Mod 256
For compte = 1 To 16
cle(compte) = cle(compte) Xor c
Next compte
c = c Xor (cfc Xor cfd)
d = (((c / 16) * 16) - (c Mod 16)) / 16
e = c Mod 16
Form1.Text3 = Form1.Text3 + Chr$(&H61 + d) ' d+&h61 give one letter range from a to p for the 4 high bits of c
Form1.Text3 = Form1.Text3 + Chr$(&H61 + e) ' e+&h61 give one letter range from a to p for the 4 low bits of c
Next fois
End SubPrivate Sub decrypt()
Form1.Text2 = ""
si = 0
x1a2 = 0
i = 0
For fois = 1 To 16
cle(fois) = 0
Next fois
champ1 = Form1.Text1
lngchamp1 = Len(champ1)
For fois = 1 To lngchamp1
cle(fois) = Asc(Mid(champ1, fois, 1))
Next fois
champ1 = Form1.Text3
lngchamp1 = Len(champ1)
For fois = 1 To lngchamp1
d = Asc(Mid(champ1, fois, 1))
If (d - &H61) >= 0 Then
d = d - &H61 ' to transform the letter to the 4 high bits of c
If (d >= 0) And (d <= 15) Then
d = d * 16
End If
End If
If (fois <> lngchamp1) Then
fois = fois + 1
End If
e = Asc(Mid(champ1, fois, 1))
If (e - &H61) >= 0 Then
e = e - &H61 ' to transform the letter to the 4 low bits of c
If (e >= 0) And (e <= 15) Then
c = d + e
End If
End If
Assemble
If inter > 65535 Then
inter = inter - 65536
End If
cfc = (((inter / 256) * 256) - (inter Mod 256)) / 256
cfd = inter Mod 256
c = c Xor (cfc Xor cfd)
For compte = 1 To 16
cle(compte) = cle(compte) Xor c
Next compte
Form1.Text2 = Form1.Text2 + Chr$(c)
Next fois
End SubPrivate Sub Command1_Click()
If Len(Form1.Text1) > 16 Then
MsgBox ("The password must be <=16 characters")
Else
If Len(Form1.Text1) > 0 Then
crypt
End If
End If
End Sub
var
Form1: TForm1; x1a0:array[0..7] of longint;
cle:array[1..16] of longint;
x1a2:longint; inter,res,ax,bx,cx,dx,si,tmp:longint;
i:longint;
c:Byte;implementation{$R *.dfm}function TForm1.GetAsc(var str:string):integer;
var
cTmp:char;
bRen:integer;
begin
cTmp := str[1];
bRen := ord(cTmp);
GetAsc := bRen;
end;function Tform1.crypt(var sYue,sMing:string):string;
var
fois,compte:integer;
champ1:string;
lngchamp1:integer;
d,e:integer;
stmp:string;
cfc,cfd:integer;
sMi:string;
begin
stmp := '';
sMi := '';
si := 0;
x1a2 := 0;
i := 0; For fois := 1 To 16 do
cle[fois] := 0; champ1 := sYue;
lngchamp1 := Length(champ1); For fois := 1 To lngchamp1 do
begin
stmp := MidStr(champ1, fois, 1);
cle[fois] := GetAsc(stmp);
end; champ1 := sMing;
lngchamp1 := Length(champ1);
For fois := 1 To lngchamp1 do
begin
stmp := MidStr(champ1, fois, 1);
c := GetAsc(stmp); Assemble(); If inter > 65535 Then
inter := inter - 65536; cfc := Round((((inter / 256) * 256) - (inter Mod 256)) / 256);
cfd := inter Mod 256; For compte := 1 To 16 do
cle[compte] := cle[compte] Xor c; c := c Xor (cfc Xor cfd); d := Round((((c / 16) * 16) - (c Mod 16)) / 16);
e := c Mod 16; sMi := sMi + Chr(97 + d);
sMi := sMi + Chr(97 + e);
end;
crypt := sMi;
end;function Tform1.decrypt(var sYue,sMi:string):string;
var
fois,compte:integer;
champ1:string;
lngchamp1:integer;
d,e:integer;
stmp:string;
cfc,cfd:integer;
sMing:string;
begin
sMing := '';
si := 0;
x1a2 := 0;
i := 0; For fois := 1 To 16 do
cle[fois] := 0;
champ1 := sYue;
lngchamp1 := Length(champ1); For fois := 1 To lngchamp1 do
begin
stmp := MidStr(champ1, fois, 1);
cle[fois] := GetAsc(stmp);
end; champ1 := sMi;
lngchamp1 := Length(champ1); fois :=1;
while fois<= lngchamp1 do
begin
stmp := MidStr(champ1, fois, 1);
d := GetAsc(stmp);
If (d - 97) >= 0 Then
begin
d := d - 97;
If (d >= 0) And (d <= 15) Then
d := d * 16;
end; If (fois <> lngchamp1) Then
fois := fois + 1; stmp := MidStr(champ1, fois, 1);
e := GetAsc(stmp);
If (e - 97) >= 0 Then
begin
e := e - 97;
If (e >= 0) And (e <= 15) Then
c := d + e;
end; Assemble(); If inter > 65535 Then
inter := inter - 65536; cfc := Round((((inter / 256) * 256) - (inter Mod 256)) / 256);
cfd := inter Mod 256; c := c Xor (cfc Xor cfd); For compte := 1 To 16 do
cle[compte] := cle[compte] Xor c; sMing := sMing + Chr(c);
fois := fois+1;
end;
decrypt := sMing;
end;procedure Tform1.ccode();
begin
dx := (x1a2 + i) Mod 65536;
ax := x1a0[i];
cx := 346;
bx := 20021; tmp := ax;
ax := si;
si := tmp; tmp := ax;
ax := dx;
dx := tmp; If (ax <> 0) Then
ax := (ax * bx) Mod 65536; tmp := ax;
ax := cx;
cx := tmp; If (ax <> 0) Then
begin
ax := (ax * si) Mod 65536;
cx := (ax + cx) Mod 65536;
end; tmp := ax;
ax := si;
si := tmp;
ax := (ax * bx) Mod 65536;
dx := (cx + dx) Mod 65536; ax := ax + 1; x1a2 := dx;
x1a0[i] := ax; res := ax Xor dx;
i := i + 1;
end;procedure Tform1.assemble();
begin
x1a0[0] := ((cle[1] * 256) + cle[2]) Mod 65536;
ccode();
inter := res; x1a0[1] := x1a0[0] Xor ((cle[3] * 256) + cle[4]);
ccode();
inter := inter Xor res;; x1a0[2] := x1a0[1] Xor ((cle[5] * 256) + cle[6]);
ccode();
inter := inter Xor res;; x1a0[3] := x1a0[2] Xor ((cle[7] * 256) + cle[8]);
ccode();
inter := inter Xor res;; x1a0[4] := x1a0[3] Xor ((cle[9] * 256) + cle[10]);
ccode();
inter := inter Xor res; x1a0[5] := x1a0[4] Xor ((cle[11] * 256) + cle[12]);
ccode();
inter := inter Xor res; x1a0[6] := x1a0[5] Xor ((cle[13] * 256) + cle[14]);
ccode();
inter := inter Xor res; x1a0[7] := x1a0[6] Xor ((cle[15] * 256) + cle[16]);
ccode();
inter := inter Xor res; i := 0;
end;结贴,谢谢各位。