大家好,请教一个问题。 (100分)

  • 主题发起人 主题发起人 miniapollo
  • 开始时间 开始时间
M

miniapollo

Unregistered / Unconfirmed
GUEST, unregistred user!
最近写程序过程中,调用一个dll(用des算法写的一个字符串加密模块)时,程序运行并且结果也正确,只是在关闭程序时出现
“project demo.exe raised exception class EInvalidPointer with
message 'Invalid pointer operation'. Process stopped . Use step or run to continue”

源程序如下:

unit main;

interface

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

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit3: TEdit;
Button3: TButton;
Edit4: TEdit;
Label4: TLabel;

procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
end;

var
Form1: TForm1;

procedure Enpkg(const content:Pchar;const Encrypted:Pchar;const key:Pchar);
procedure EncryptPswd(const content:Pchar;const Encrypted:Pchar;const Key:Pchar)
stdcall external 'des.dll';

implementation

{$R *.DFM}

procedure TForm1.Button2Click(Sender: TObject);
begin
edit1.Text:='';
edit2.Text:='';
edit3.Text:='';
edit4.Text:='';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Skey,scontent,sencrypted:Pchar;
indata:array [0..59] of char;
inkey:array [0..8] of char;
begin
getmem(skey,8);
getmem(scontent,60);
getmem(sencrypted,120);
//for skey;
fillchar(inkey,9,0);
strlcopy(inkey,Pchar(edit4.Text),length(edit4.Text));
strlcopy(skey,inkey,length(edit4.Text));
//for scontent;
fillchar(indata,60,0);
strlcopy(indata,Pchar(edit1.Text),length(edit1.Text));
strlcopy(scontent,indata,length(edit1.Text));

enpkg(scontent,sencrypted,skey);
edit2.Text:=sencrypted;
end;

procedure Enpkg(var content:Pchar;var Encrypted:Pchar;const key:Pchar);
var
Skey,scontent,sencrypted:Pchar;
intest1:array [0..4095] of char
//输入包;
outtest:array [0..4095] of char
//输出包;
tihuan:array [0..8] of char
//8位输入中转;
tohuan:array [0..12] of char
//12位输出中转;
i,j,k,m,lengths:integer;
k1:string
//按每8位截取待加密字符串;
begin
skey:=key;
sencrypted:=Encrypted;
fillchar(intest1,4096,0);
//将待加密字符串copy to Array中;
strcopy(intest1,content);

fillchar(outtest,4096,0);
fillchar(tihuan,9,0);
fillchar(tohuan,13,0);

//按每8位计算待加密循环次数 j;
lengths:=length(content)+4;
if (lengths mod 8)=0 then
j:=lengths
else
j:=lengths+8-lengths mod 8;
j:=round(j/8);

// 加密过程;
for i:=0 to j do
begin
k1:='';
for k:=0 to 7 do
k1:=k1+intest1[i*8+k];
scontent:=Pchar(k1);
encryptpswd(scontent,sencrypted,skey);
strlcopy(tohuan,sencrypted,12);
for m:=0 to 11 do
outtest[i*12+m]:=tohuan[m];
end;
strcopy(encrypted,outtest);
end;
end.

请各位大侠帮忙会诊,多谢。
 
请问有没有高手指点、指点!
 
我看到这里了
getmem(skey,8);
getmem(scontent,60);
getmem(sencrypted,120);

没见到FreeMem!你看看是不是这个问题
 
to Soar:
程序中原来也有Freemem这三个Pchar,但是加了之后反而报错误的指针操作,去掉后Freemem该函数
倒是正常了,但是关闭程序时又出现我提出的”project demo.exe raised exception class EInvalidPointer with
message 'Invalid pointer operation'. Process stopped . Use step or run to continue“
有什么不妥的地方,请再指正。

to all:
大家努力啊,我还有100分做为奖赏。
 
可能是缺freemem关系,或没初始化。至于是不是需要到W2K中验证,或许我的话是错误的。
 
应该是没有Free掉的原因
 
to hamsoft:
freemem我已经试过了,报错误的指针操作。
to kals:
的确应该是内存释放的问题。应该两种情况 1.指针在Dll中已经释放,而在程序运行完成后在释放资源时又重复释放指针;2.指针释放的地址错误。你觉得呢?
 
register、cdecl、pascal、stdcall和safecall。五种调用模式除了cd ecl外,都是由过程和函数在返回时清除堆栈中的参数,
而对于 cdecl模式,需由调用者在调用结束时清除堆栈中的参数。
而你用的是stdcall模式,所以是由过程和函数在返回时清除堆栈中的参数,
至于出错可能是如miniapollo所说指针释放的地址错误。
 
你在单元中加入uses ShareMem试试看
 
to zswenyun
加入uses ShareMem 也无效果.看看有没有别的想法?
 
問題應出在,
getmem(skey,8)
strlcopy(skey,inkey,length(edit4.Text));
我看你的程式碼, SKey最大可為8位元, 你宣告SKey時, 只宣告了8 bytes
但在StrLCopy時, 還會包字串結尾符#0, 如果長度為8, 則StrLCopy實際會Copy 9 Bytes
(包含結尾字符#0), 所以如果輸入的Key為8 bytes, 則會出現錯誤
其它的則可能會有相同的問題
建議如果在處理PChar時,在GetMem時, 記得要比最大長度再加一
//
另外確保內存資源有效釋放, 建議改為如下:

getmem(skey,8);
getmem(scontent,60);
getmem(sencrypted,120);
try


finally
freemem(skey,8);
freemem(scontent,60);
freemem(sencrypted,120);
end;
 
更正上面的回覆的最後, 跟據你的Code, GetMem的大小應為9, 61, 121
 
check your code in dll,whether there are mem problem.
 
学习学习^_^
 

Similar threads

I
回复
0
查看
843
import
I
I
回复
0
查看
529
import
I
I
回复
0
查看
830
import
I
I
回复
0
查看
499
import
I
后退
顶部