我试了试在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.   

    按照WinAPI的基本设计思想: 动态内存的分配和释放应该交给调用者去完成, 而不要在被调用的函数中去完成。
      

  2.   

    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;
      

  3.   

    忘记取消 Bshuju:=nil; 了,这句没有用了。
      

  4.   

    应如下:-----------------------------------------------------------
    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;
    -------------------------