我写了一个简单的dll 里面就一个函数 计算1个数的的2倍。
dll程序如下:
dpr文件:library MyDLL;uses
  SysUtils,
  Classes,
  Base in 'Base.pas';{$R *.res}exports
    Doubl;
begin
end.Base.pas文件:unit Base;interface
  function Doubl(N:integer):integer;stdcall;
implementation
  function Doubl(N:integer):integer;stdcall;
  begin
      Result:=N*2;
  end;
end.测试程序很简单,就是在窗体的按钮事件里面调用Dll的方法:
代码如下:unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TDoubl = function(N:integer):integer;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
orde:integer;
Moudel:THandle;
pfuc:TFarProc;
begin
  Moudel := Loadlibrary('MyDLL.dll');
  if Moudel > 32 then
  begin
    pfuc := GetProcAddress(Moudel,'Doubl');
    orde := TDoubl(pfuc)(4);
    showmessage(IntToStr(orde));
  end;
  FreeLibrary(Moudel);
end;
end.现在dll可以正常加载和卸载,但是函数调用结果不对。传入的是4,返回是:2486504(好像是函数的入口地址,不清楚了)。然后就出现异常。
实在不明白为什么,使望各位高手指点迷经。

解决方案 »

  1.   

    TDouble= function Doubl(N:integer):integer;stdcall;
    var
    orde:integer;
    Moudel:THandle;
    pfuc:TDoubl;
    begin
      Moudel := Loadlibrary('MyDLL.dll');
      if Moudel > 32 then
      begin
        @pfuc := GetProcAddress(Moudel,'Doubl');
        orde := pfuc(4);
        showmessage(IntToStr(orde));
      end;
      FreeLibrary(Moudel);
    end;
    这样试试。
      

  2.   

    TDoubl(pfuc)(4)的结合顺序可能不对,所以返回TDoubl的地址
    最好分开写
    type
      TDoubl = function(N:integer):integer;stdcall;
    ...
    procedure TForm1.Button1Click(Sender: TObject);
    var
    orde:integer;
    Moudel:THandle;
    Tp:TFarProc;
    pfuc:TDoubl;
    begin
      Moudel := Loadlibrary('MyDLL.dll');
      if Moudel > 32 then
      begin
        Tp := GetProcAddress(Moudel,Pchar('Doubl'));
        pfuc := TDoubl(Tp);//可以和上一句合并为pfuc := TDoubl(GetProcAddress(Moudel,Pchar('Doubl')));
        orde:=pfuc(4);
        showmessage(IntToStr(orde));
      end;
      FreeLibrary(Moudel);
    end;
      

  3.   

    你们两个说的都对啊,关键是TDouble=   function   Doubl(N:integer):integer;stdcall; 这句里的stdcall原来的时候我没有写。我现在还不明白stdcall的作用,谁能给我说一下啊?
      

  4.   

    还有 我想输出函数的地址来看看怎么办?
     showmessage(IntToStr(@@pfuc)); 不行 
      

  5.   

    stdcall是参数调用方式的一种,即参数从右到左依次调用入函数,变量在其作用域内有效否则将释放
    对于定义给外部调用的函数和过程,用stdcall声明更优,另外还有register, pascal, cdecl, safecall
    你在help里查找stdcall有详细说明输出函数地址:
    showmessage(format('%p',[@functionname]));
      

  6.   

    楼上说的对,一般建议调用dll都使用stdcall,