首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

调用DLL时正确,但退出时提示异常

2012-02-29 
调用DLL时正确,但退出时提示错误我试了试在DLL中FREEMEM指针后函数返回的数据是错误的,不能正确返回。下面

调用DLL时正确,但退出时提示错误
我试了试在DLL中FREEMEM指针后函数返回的数据是错误的,不能正确返回。
下面是DLL中的函数
-----------------------
function   EditionTo_55(var   idhao:integer):Pointer;export;far;
var
    c_shuju:array   of   byte;
begin
    try
        GetMem(c_shuju,4);
       
        c_shuju[0]:=188;
        c_shuju[1]:=250;
        c_shuju[2]:=idhao;
        c_shuju[3]:=55;
        result   :=   @c_shuju[0];
        //Freemem(c_shuju,4);
    except
        result   :=   nil;
    end;
end;
EXE中的调用。
-------------------------------------------------
procedure   TForm1.Button1Click(Sender:   TObject);
var
    H_TOP:HWND;    
    EditionTo_55:TEditionTo_55;  
    hh:Pointer;
    idhao:integer;
    Bshuju:array   of   byte;
begin
      Bshuju:=nil;
      idhao:=2;
      H_TOP:=LoadLibrary(pchar( 'publicdll.dll '));
      EditionTo_55:=GetProcaddress(H_TOP, 'EditionTo_55 ');
      hh:=EditionTo_55(idhao);
      setlength(Bshuju,sizeof(hh));
      Move(hh^,PChar(@Bshuju[0])^,sizeof(hh));
      hh:=nil;
      Freemem(hh);
      Freelibrary(H_TOP);
end;
-------------------------
我是用动态方法调用的。请高手指点指点。

[解决办法]
1.指针不可以作为返回值
2.在WIN32里,不需要 far 定义。
3.要指明缓冲区长度
4.因为DLL申请的空间与调用者在相同空间内,缓冲区由调用函数申请和销毁。
5.动态数组可以用SetLength申请空间,回收可以靠系统收回,也可以手动用SetLength收回。
6.pchar( 'publicdll.dll ')这里不需要PCHAR声明。
function EditionTo_55(const ID: Byte; shuju: PByte; const iLen: Integer): Boolean; export;
var
c_shuju: array of Byte;
begin
Result := False;
if iLen < 4 then
Exit;
PByte(c_shuju) := shuju;
c_shuju[0] := 188;
c_shuju[1] := 250;
c_shuju[2] := ID;
c_shuju[3] := 55;
Result := True;
end;

procedure TfMainTest1.TntButton1Click(Sender: TObject);
var
H_TOP:HWND;
EditionTo_55: TEditionTo_55;
idhao: Byte;
Bshuju: array of byte;
begin
Bshuju:=nil;
idhao:=2;

H_TOP:=LoadLibrary(pchar( 'publicdll.dll '));
EditionTo_55:=GetProcaddress(H_TOP, 'EditionTo_55 ');

SetLength(Bshuju, 4);
EditionTo_55(idhao, @Bshuju[0], 4);
Caption := IntToHex(PLongWord(@Bshuju[0])^, 8);
Freelibrary(H_TOP);
end;

[解决办法]
应如下:

-----------------------
Exports
EditionTo_55;
function EditionTo_55(idhao: Byte;var iLen: Integer):Pointer;stdcall;
var
c_shuju:array of byte;
begin
try
Result := nil;
iLen := 0;
SetLength(c_shuju,4);
c_shuju[0]:=188;
c_shuju[1]:=250;
c_shuju[2]:=idhao;
c_shuju[3]:=55;
GetMem(Result,4);
if Assigned(Result) then
begin
CopyMemory(Result,@c_shuju[0],4);
iLen := 4;
end;
except
if Assigned(Result) then


FreeMem(Result);
result := nil;
iLen := 0;
end;
c_shuju := nil;
end;
EXE中的调用。
-------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
H_TOP:HWND;
EditionTo_55:TEditionTo_55;
hh:Pointer;
idhao: Byte;
iLen: Integer;
Bshuju:array of byte;
begin
H_TOP:=LoadLibrary(pchar( 'publicdll.dll '));
EditionTo_55:=GetProcaddress(H_TOP, 'EditionTo_55 ');
idhao:=2;
hh:=EditionTo_55(idhao,iLen);
if Assigned(hh) then
begin
setlength(Bshuju,iLen);
CopyMemory(@Bshuju[0],hh,iLen);
Freemem(hh);
hh := nil;
Bshuju := nil;
end;
Freelibrary(H_TOP);
end;
-------------------------

热点排行