调用dll时,提示错误:'Invalid pointer operation'?
解决方案 »
- findfirst函数中遇到的问题·能讲解一下吗,谢谢
- 用什么工具把数据导入到SQL SERVER数据库?(除了自带的DTS)
- 哪里找得到XPMan单元?
- 数据库后台查询问题,急急急,在线等待,马上给分
- 请教高手!!!能否这样通过动态创建视图,然后根据视图中的字段创建报表???
- 为什么鼠标左键不能触发MouseDown事件?苦恼啊!!!!
- 如何在一个窗体里调用另一个窗体Private下的过程?
- SOS!
- access是不是不允许字段值空啊?但是我必须要有一些字段值空,该怎么办?在线等待……
- 问一个关于ADSL的问题
- 想学delphi~!谁有相关的初学者资料!
- 如何在Delphi中调用SQL Server中的存储过程?
为什么?
‘的参数传递方式是否设为stdcall的windows默认方式’是什么意思?
我在函数的调用中用了呀!dll的unit中的接口我也声明了!
是为什么?
只是我在关掉窗体的时候报了同样的错误!这是什么原因?
我的意思是现在调用dll的功能都实现了,结果也得到了!
只是关闭调用端的窗体时,提示了和刚才一样的错误!
不知说清楚了没有?
你最好贴一写代码出来
一、窗体端
function DecryStrHex(StrHex, Key: string):string;stdcall;external 'Endry_pro.dll';
function EncryStrHex(Str, Key: String): String;stdcall;external 'Endry_pro.dll';
procedure libexit;stdcall;external 'Endry_pro.dll';
var
Form1: TForm1;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);begin
Edit4.Text:=EncryStrHex(Edit1.Text,Edit1.Text);
end;
unit Encry;
interface
uses sharemem,SysUtils;
type
TKeyByte = array[0..5] of Byte;
TDesMode = (dmEncry, dmDecry);
function EncryStrHex(Str, Key: String): String;stdcall;
function DecryStrHex(StrHex, Key: String): String;stdcall;
var
subKey: array[0..15] of TKeyByte; //存产生的16个密钥
implementation
function EncryStrHex(Str, Key: String):String;stdcall;
var
StrResult, TempResult, Temp: String;
I: Integer;
begin
TempResult := EncryStr(Str, Key);
StrResult := '';
for I := 0 to Length(TempResult) - 1 do
begin
Temp := Format('%x', [Ord(TempResult[I + 1])]);
if Length(Temp) = 1 then Temp := '0' + Temp;
StrResult := StrResult + Temp;
end;
Result := StrResult;
end;
///////////
function EncryStr(Str, Key: String): String;
var
StrByte, OutByte, KeyByte: array[0..7] of Byte;
StrResult: String;
I, J: Integer;
begin
//判断明文长度是否大于零并且最后是否已null作为结束符
if (Length(Str) > 0) and (Ord(Str[Length(Str)]) = 0) then
raise Exception.Create('Error: the last char is NULL char.');
//若密码的长度小于8,按标准加入符号
if Length(Key) < 8 then
while Length(Key) < 8 do Key := Key + Chr(0);
while Length(Str) mod 8 <> 0 do Str := Str + Chr(0);
//将前八位的位置记录下来,并取生成密钥
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);
makeKey(keyByte, subKey);
//产生玩16个密钥后开始加密数据
StrResult := ''; for I := 0 to Length(Str) div 8 - 1 do
begin
for J := 0 to 7 do
StrByte[J] := Ord(Str[I * 8 + J + 1]);
desData(dmEncry, StrByte, OutByte);
for J := 0 to 7 do
StrResult := StrResult + Chr(OutByte[J]);
end; Result := StrResult;
end;
全部换成pchar?
为什么代码不放入dll中时就没错?怎么办?
怎么写?
if strlen(key)<8 then StrCopy(ptempchar,key)
//最后在把这个填充慢就可以了
var
tempstring:pchar
...
setlength(tempstring,8);
...
if strlen(key)<8 then
begin
StrCopy(tempstring,key);
for i:=strlen(ptempchar) to 7 do
tempstring[i]:=chr(x);//注意这时你就不能填充#0了,因为会把它作为结束符
end;
Result := StrResult;
即在返回时返回一个字符串, 在动态库中不能这么做.原因很简单: 返回的字符串是在 Dll 中分配的, 在退出程序时, 主线程自动去释放字符串占用的内存空间, 而字符串的内存空间是属于 Dll 的, 这样就产生了地址越界释放的异常.
procedure DeleteStrPointer(AValue: PChar); stdcall;
begin
if Assigned(AValue) then
try
StrDispose(AValue);
except
end;
end;function EncryStrHex(Str, Key: PChar): PChar; stdcall;
begin
// ... ... // 返回动态分配的字符串
result := StrNew(PChar(strResult));
end;procedure TForm1.Button1Click(Sender: TObject);
var
pchResult: PChar;
begin
pchResult := EncryStrHex(PChar(Edit1.Text), PChar(Edit1.Text));
Edit4.Text := StrPas(pchResult); // 别忘了调用释放字符串指针
DeleteStrPointer(pchResult);
end;
procedure StrDispose(Str: PChar);
begin
if Str <> nil then
begin
Dec(Str, SizeOf(Cardinal));
FreeMem(Str, Cardinal(Pointer(Str)^));
end;
end;