例如:
DLL有个叫recivedata的函数,类型为Tstaff ,这个Tstaff是record,有 data1和data2两个值.
问题:我如何取得DLL中的这个recivedata.data1和recivedata.data2这两个值DLL文件源代码如下:
library Project2;uses
  SysUtils,
  Classes;type
Tstaff = record
  data1:integer;
  data2:integer;
end;{$R *.res}function recivedata:Tstaff;stdcall;
begin
result.data1:=20;
result.data2:=30;
end;function test:integer;stdcall;
begin
result:=55;
end;
exports recivedata,test;
begin
end.主程序源代码如下:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Timer1: TTimer;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;type
Tstaff = record
  data1:integer;
  data2:integer;
end;
var
  Form1: TForm1;implementation{$R *.dfm}function recivedata:Tstaff;external 'project2.dll';
function test:integer;external 'project2.dll';
procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Lines.Add(inttostr(recivedata.data1));
memo1.Lines.Add(inttostr(recivedata.data2));
end;procedure TForm1.Button2Click(Sender: TObject);
begin
memo1.Lines.Add(inttostr(test));
end;end.
我调用test,返回普通的integer完全正常,但调用record类就有问题....
超急问题.....请达人帮忙解答...小弟先谢谢了.....

解决方案 »

  1.   


    原因见楼上!DLL部分
    type
      PStaff = ^TStaff;
      TStaff = record
        data1:integer;
        data2:integer;
    end;function recivedata( MyTest:PStaff):boolean;stdcall;
    begin
      Result:=True;
      try
        //操作
        MyTest^.data1:=20;
        MyTest^.data2:=30;
      except
        Result:=False;
      end;
    end;exports
      recivedata ;//主调程序
    type
      PStaff = ^TStaff;
      TStaff = record
        data1:integer;
        data2:integer;
      end;
      TGetRecieveData=function(MyTest:PStaff):boolean;stdcall;function TForm1.GetData: boolean;
    var
      DllHnd: THandle;
      GetRDProc: TGetRecieveData;
      Stf:PStaff;
    begin
      DllHnd := LoadLibrary(PChar('project1.dll'));
      try
        if (DllHnd <> 0) then
        begin
           @GetRDProc :=GetProcAddress(DllHnd, 'recivedata');
           if (@GetRDProc<>nil) then
           begin
             New(Stf);
             try
               if not GetRDProc(Stf) then  ShowMessage('获取值错误');
               //Showmessage('result='+Inttostr(Stf^.data1));
             finally
               Dispose(Stf);
             end;
           end;
        end
        else
        begin
          Application.MessageBox(PChar('DLL加载出错,DLL可能不存在!'), PChar('错误'),
              MB_ICONWARNING or MB_OK);
        end;
      finally
        FreeLibrary(DllHnd);
      end;
    end;
      

  2.   

    谢谢楼上的朋友解答.....现在还有一个问题....为什么我一传参数进去就会出错....
    DLL部分
    library Project2; uses 
      SysUtils, 
      Classes; {$R *.res} function test(var mystr:shortstring):boolean;stdcall; 
    begin
    mystr:='ccccccc'; 
    result:=true; 
    end; 
    exports test; 
    begin 
    end. 主程序源代码如下: 
    unit Unit1; interface uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls, ExtCtrls; type 
      TForm1 = class(TForm) 
        Memo1: TMemo; 
        Timer1: TTimer; 
        Button1: TButton; 
        Button2: TButton; 
        procedure Button1Click(Sender: TObject); 
        procedure Button2Click(Sender: TObject); 
      private 
        { Private declarations } 
      public 
        { Public declarations } 
      end; 
    var 
      Form1: TForm1; 
    implementation {$R *.dfm} function test(var mystr:shortstring):boolean;external 'project2.dll'; 
    procedure TForm1.Button2Click(Sender: TObject); 
    var
    myvar:shortstring;
    begin 
    test(myvar);
    memo1.Lines.Add(myvar); 
    end; end. 
      

  3.   


    //注:需要在DLL函数的参数中加上一个变参,用来表示mystr被DLL函数加工后的长度,以便通知主调函数释放内存的长度,我这里为省事,就不写了,这部分内容僵哥曾经仔细讲过,可查询一下以前的贴子
    DLL部分
    function test(mystr:PChar):boolean;stdcall;
    var
      str:string;
    begin
      result:=False;
      str:='ccccccc';
      CopyMemory(mystr,PChar(str),Length(str));
      result:=true;
    end;
    主调:
    var
       mystr:PChar;
    begin
       GetMem(mystr,100 );
       test(mystr);
       showmessage(mystr);
       FreeMem(mystr);
    end;
      

  4.   

    此外:
    function test(var mystr:shortstring):boolean;external 'project2.dll'; //声明少加stdcall了应改为
    function test(var mystr:shortstring):boolean;stdcall;external 'project2.dll';
      

  5.   

    改成pchar还是一样出错提示...
    提示:access violation at address 00B53F11. read of address FFFFFFFF
      

  6.   

    哈哈....谢谢楼上的朋友....所有问题都是因为此外: 
    function test(var mystr:shortstring):boolean;external 'project2.dll'; //声明少加stdcall了 应改为 
    function test(var mystr:shortstring):boolean;stdcall;external 'project2.dll'; 是这个引起的.....是我大意了....害我郁闷了一上午..
    谢谢...结贴....