在delphi中怎样调用dll??能不能给出一段成熟稳定的代码。急!特急!

时间:2022-12-09 19:08:36
在delphi中怎样调用dll??能不能给出一段成熟稳定的代码。急!特急!

11 个解决方案

#1


将你的dll中的函数在程序中声明。如下。
   
function IsInterSected(PAx,PAy,PBx,PBy,PCx,PCy,PDx,PDy:Single;out PCommonX,PCommonY:Single):Boolean;stdcall;external 'GagaMath.dll';

#2


下面的代码为驱动扫描仪,扫描发票,然后识别成文字,在第一次调用时可以扫描识别,但是再次点击扫描按钮时,程序退出,请问各位怎么办?特急!
procedure Tmainform.N9Click(Sender: TObject);
type
  TIntFunc=function(i:pchar):integer;stdcall;
var
  Th:Thandle;
  Tf1,Tf2:TIntFunc;
  Tp1,Tp2:TFarProc;
  lib:string;
  Scanner,filepath:pchar;
  //sd:array[1..19] of char;
  dwRetn:integer;
begin
  //showmessage(' 扫描前请先装入发票!');
  lib:=p_path+'\EtcVatScan.dll';
  Th:=LoadLibrary(pchar(lib)); {装载DLL}
  if Th>0 then
  try
    Tp1:=GetProcAddress(Th,PChar('C_getScanner')); //获取扫描仪类型
    Tp2:=GetProcAddress(Th,PChar('C_getetcvatfile'));//指令扫描仪进行扫描识别,并返回最后的识别文本文件ETCVAT.TXT全路径。
    if (Tp1<>nil) and (Tp2<>nil)  then
    if Tp1<>nil  then
    begin
      Tf1:=TIntFunc(Tp1);
      GetMem(Scanner,60);//为将要得到的名字分配内存
      dwRetn := Tf1(Scanner);
      showmessage(string(Scanner)+'as:'+inttostr(dwRetn));
      FreeMem(Scanner,0); // 释放分配的内存
      if dwRetn=1 then
      begin
        GetMem(filepath,200);
        Tf2:=TIntFunc(Tp2);
        dwRetn := Tf2(filepath);
        if dwRetn=0 then
          showmessage(string(filepath)+'as:'+inttostr(dwRetn))
        else
          showmessage('as:'+inttostr(dwRetn));
          FreeMem(filepath,0); // 释放分配的内存
        end;
      end
      else
        ShowMessage('C_getScanner函数没有找到');
  finally
    FreeLibrary(Th); //释放DLL
  end
  else
    ShowMessage('扫描库'+lib+'未找到,加载不成功!');
end;

#3


第二次是自动退出

#4


我这里有一段代码:
调用部分:
implementation

{$R *.DFM}
    function  Set_Darkness ( darkness:integer):integer;stdcall;external 'WINPPLB.DLL';
    function  Set_Speed(speed:integer):integer; stdcall;external 'WINPPLB.DLL';
    function  CreatePrn    ( selection:integer;FileName:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Print_Out    ( copypiece:integer):integer;stdcall;external 'WINPPLB.DLL';
    function  Prn_Text     ( x,y,ori,font,hor_factor,ver_factor:integer;mode:char;data:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Prn_Barcode  ( x,y,ori:integer;typee:pchar;narrow,width,height:integer;human:char;data:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Prn_Text_TrueType ( x,y,FSize:integer;FType:pchar;Fspin,FWeight,FItalic,FUnline,FStrikeOut:integer;id_name,data:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Get_Pcx  ( x,y:integer;filename:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Load_Pcx (x,y:Integer;filename:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Get_Graphic_ColorBMP( x,y:integer; filename:pchar):integer;stdcall;external 'WINPPLB.DLL';
    Procedure ClosePrn     ();stdcall;external 'WINPPLB.DLL';

引用部分
procedure TfrmYuXin.BitBtn1Click(Sender: TObject);
var
//M,N:Array of Integer;
//s,t:integer;
//c,d:integer;
e,f:integer;//垂直起始位置和间隔距离
g,h:integer;//左起点位置和字体大小设定
begin
    mainpath:=ExtractFilePath(Application.ExeName);
    Criterions:=TiniFile.Create(mainpath+'Criterion.ini');
    Materials:=TiniFile.Create (mainpath+'Material.ini');
    Inner:=TiniFile.Create(mainpath+'Inner.ini');

     CreatePrn(1, pchar('pplb.txt'));
     Set_Speed(strtoint(cboSpeed.Text));
     Set_Darkness(strtoint(cboDarkness.Text));

   e:=strtoint(edtHeight.Text);
   f:=strtoint(edtLevel.Text);
   g:=strtoint(edtLeft.Text);
   h:=strtoint(edtFonts.Text);


   {文字档的排版设定}
    {品名}
    Prn_Text_TrueType(g, e, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('NA'), pchar('品名:'+edtName.Text ));
    {货号}
    Prn_Text_TrueType(g, e+f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AZ'), pchar('货号:'+edtNo.Text ));
    {型号}
    Prn_Text_TrueType(g, e+2*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('ZA'), pchar('型号:'+cboType.Text ));
    {价格}
    Prn_Text_TrueType(g, e+3*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AB'), pchar('价格:'+edtPrice.text+'.00'));
    {面料}
    Prn_Text_TrueType(g, e+4*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AC'), pchar('面料:'+edtMaterial1.Text+'%'+cboMaterial1.Text  ));
    if edtMaterial2.text<>'' then
    Prn_Text_TrueType(105, e+5*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AD'), pchar(edtMaterial2.text+'%'+cboMaterial2.Text));
    if edtMaterial3.text<>'' then
    Prn_Text_TrueType(105, e+6*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AE'), pchar(edtMaterial3.text+'%'+cboMaterial3.Text));
    if edtMaterial4.text<>'' then
    Prn_Text_TrueType(105, e+7*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('EA'), pchar(edtMaterial4.text+'%'+cboMaterial4.Text));

#5


这是一个打印软件的一部分,希望对你能有帮助!

#6


记得在Delphi3的时候Windows单元里没有AnimateWindow
我当时是这样声明的!
function AnimateWindow(hWnd: HWND; dwTime: DWORD; dwFlags: DWORD): BOOL; stdcall;external user32 name 'AnimateWindow';

#7


DELPHI 中动态链接库的使用 
作者:  评价:  上站日期: 2001-05-09  
内容说明:  
来源:  

--------------------------------------------------------------------------------

  在DELPHI中,有两种方法可用于调用一个储存在DLL(动态链接库)中的过程。 

一、 调用方法 

1、 静态调用或显式装载使用一个外部声明子句,使DLL在应用程序开始执行前即被装入。例如: 

Function instring (sourcestr: Pchar ;
check: char): integer; far; external ‘ demostr’
这种方式要在单元的interface 部分用external 指示字列出要从DLL中调用的例程。Far 指令表明可以被其他段,例如其他单元调用的子例程。所有在单元接口中声明的子例程在缺省情况下都是Far类型的,其相反的指令是near。 

如果external 后什么也不跟,必须用 {$ L } 编译指令预先指定一个DLL名字,如: 

{ $ L Mydlls.dll }
Procedure setstring(var str: string) ;
stdcall ; external
但是使用静态调用方法时,程序无法在运行时间里决定DLL的调用。在DELPHI中使用DLL时,例程的标识符必须与DLL中相应输出例程的标识符完全一致(尽管DELPHI本身大小写不敏感)。 

2、 动态调用或隐式装入 

使用WINDOWS API 函数 Loadlibrary 和GetprocAddress可以实现在运行时间里的动态装载DLL,并调用其中的过程。 

例如: 

      Type TMyProc=Procedure (Param:Pchar ) ;Stdcall;
      Var MyProc: TMyproc;
       MyHandle:THandle;
       MyHandle:=LoadLibrary (‘Mydll’) ;
       If MyHandle<  =0 then
        Raise Exception.Create
        ( ‘动态链接库调用失败,错误代码
        是:’+Inttostr(Getlasterror))
        else 
         @MyProc:=GetProcAddress(MyHandle,’demoproc’);
       if not Assigned(MyProc) then
        Raise Exception.Create('GetProcAddress 
        调用失败,错误代码
           是:’+inttostr(getlasterror))
        else MyProc(Pchar(‘a string’));
        Freelibrary(Myhandle); // 卸载DLL
二、 调用方式 

1、 通过过程、函数名; 

2、 通过过程、函数别名; 

3、 通过过程、函数的顺序号 

例:Function Getstring : string ; stdcall ; external ‘Mydlls.dll’ name ‘Mygetstr’name 子句指定函数名Getstring 改为Mygetstr,当程序调用这个例程时,使用Mygetstr这个名字;Function Getstring : string ; stdcall ; external ‘Mydlls.dll’ index 5 Index 子句通过索引号引入例程可以减少DLL的加载时间。 

三、 调用约定 

调用约定,是指调用例程时参数的传递顺序。DELPHI中DLL支持的调用约定有: 

调用约定 参数传递顺序
Register 从左到右
Pascal 从左到右
Stdcall 从右到左
Cdecl 从右到左
Safecall 从右到左
使用Stdcall 方式,能保证不同语言写的DLL的兼容性,同时它也是WINDOWS API的约定方式;Delphi 3。0、4。0的默认调用方式为Register ;Cdecl是采用 C/C++的调用约定,适用于DLL是由C++语言编写的;Safecall 是适合于声明OLE对象中的方法。 

四、 DLL中的变量和段 

一个DLL声明的任何变量都为自己私有 ,调用它的模块不能直接使用它定义的变量。要使用时必须通过过程或函数界面才能完成,对DLL来说,它永远都没有机会使用调用它的模块中的声明的变量。一个DLL没有自己的SS(堆栈段),它使用调用它的应用程序的堆栈。因此在DLL中的过程、函数不要假定DS=SS(DS为数据段)。 

 
 

#8


#9


#10


to  CSDNBowlder:这些代码好熟系哦,请问你现在在哪里呢?可以认识一下吗?

#11


procedure TForm1.Button1Click(Sender: TObject);
type
  TQTSetAppHandle = procedure(Value: THandle); stdcall;
  TQTExecute = procedure; stdcall;
var
  LibHandle: THandle;
  QTSetAppHandle: TQTSetAppHandle;
  QTExecute: TQTExecute;
begin
  LibHandle := LoadLibrary('lockscr');
  if LibHandle <> 0 then
  begin

    @QTSetAppHandle := GetProcAddress(LibHandle, 'QTSetAppHandle');
    if @QTSetAppHandle <> nil then QTSetAppHandle(Application.Handle);

    @QTExecute := GetProcAddress(LibHandle , 'QTExecute');
    if @QTExecute <> nil then
    begin
      Application.Minimize;
      Application.ProcessMessages;
      QTExecute;
    end;
    FreeLibrary(LibHandle);
  end;
end;

#1


将你的dll中的函数在程序中声明。如下。
   
function IsInterSected(PAx,PAy,PBx,PBy,PCx,PCy,PDx,PDy:Single;out PCommonX,PCommonY:Single):Boolean;stdcall;external 'GagaMath.dll';

#2


下面的代码为驱动扫描仪,扫描发票,然后识别成文字,在第一次调用时可以扫描识别,但是再次点击扫描按钮时,程序退出,请问各位怎么办?特急!
procedure Tmainform.N9Click(Sender: TObject);
type
  TIntFunc=function(i:pchar):integer;stdcall;
var
  Th:Thandle;
  Tf1,Tf2:TIntFunc;
  Tp1,Tp2:TFarProc;
  lib:string;
  Scanner,filepath:pchar;
  //sd:array[1..19] of char;
  dwRetn:integer;
begin
  //showmessage(' 扫描前请先装入发票!');
  lib:=p_path+'\EtcVatScan.dll';
  Th:=LoadLibrary(pchar(lib)); {装载DLL}
  if Th>0 then
  try
    Tp1:=GetProcAddress(Th,PChar('C_getScanner')); //获取扫描仪类型
    Tp2:=GetProcAddress(Th,PChar('C_getetcvatfile'));//指令扫描仪进行扫描识别,并返回最后的识别文本文件ETCVAT.TXT全路径。
    if (Tp1<>nil) and (Tp2<>nil)  then
    if Tp1<>nil  then
    begin
      Tf1:=TIntFunc(Tp1);
      GetMem(Scanner,60);//为将要得到的名字分配内存
      dwRetn := Tf1(Scanner);
      showmessage(string(Scanner)+'as:'+inttostr(dwRetn));
      FreeMem(Scanner,0); // 释放分配的内存
      if dwRetn=1 then
      begin
        GetMem(filepath,200);
        Tf2:=TIntFunc(Tp2);
        dwRetn := Tf2(filepath);
        if dwRetn=0 then
          showmessage(string(filepath)+'as:'+inttostr(dwRetn))
        else
          showmessage('as:'+inttostr(dwRetn));
          FreeMem(filepath,0); // 释放分配的内存
        end;
      end
      else
        ShowMessage('C_getScanner函数没有找到');
  finally
    FreeLibrary(Th); //释放DLL
  end
  else
    ShowMessage('扫描库'+lib+'未找到,加载不成功!');
end;

#3


第二次是自动退出

#4


我这里有一段代码:
调用部分:
implementation

{$R *.DFM}
    function  Set_Darkness ( darkness:integer):integer;stdcall;external 'WINPPLB.DLL';
    function  Set_Speed(speed:integer):integer; stdcall;external 'WINPPLB.DLL';
    function  CreatePrn    ( selection:integer;FileName:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Print_Out    ( copypiece:integer):integer;stdcall;external 'WINPPLB.DLL';
    function  Prn_Text     ( x,y,ori,font,hor_factor,ver_factor:integer;mode:char;data:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Prn_Barcode  ( x,y,ori:integer;typee:pchar;narrow,width,height:integer;human:char;data:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Prn_Text_TrueType ( x,y,FSize:integer;FType:pchar;Fspin,FWeight,FItalic,FUnline,FStrikeOut:integer;id_name,data:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Get_Pcx  ( x,y:integer;filename:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Load_Pcx (x,y:Integer;filename:pchar):integer;stdcall;external 'WINPPLB.DLL';
    function  Get_Graphic_ColorBMP( x,y:integer; filename:pchar):integer;stdcall;external 'WINPPLB.DLL';
    Procedure ClosePrn     ();stdcall;external 'WINPPLB.DLL';

引用部分
procedure TfrmYuXin.BitBtn1Click(Sender: TObject);
var
//M,N:Array of Integer;
//s,t:integer;
//c,d:integer;
e,f:integer;//垂直起始位置和间隔距离
g,h:integer;//左起点位置和字体大小设定
begin
    mainpath:=ExtractFilePath(Application.ExeName);
    Criterions:=TiniFile.Create(mainpath+'Criterion.ini');
    Materials:=TiniFile.Create (mainpath+'Material.ini');
    Inner:=TiniFile.Create(mainpath+'Inner.ini');

     CreatePrn(1, pchar('pplb.txt'));
     Set_Speed(strtoint(cboSpeed.Text));
     Set_Darkness(strtoint(cboDarkness.Text));

   e:=strtoint(edtHeight.Text);
   f:=strtoint(edtLevel.Text);
   g:=strtoint(edtLeft.Text);
   h:=strtoint(edtFonts.Text);


   {文字档的排版设定}
    {品名}
    Prn_Text_TrueType(g, e, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('NA'), pchar('品名:'+edtName.Text ));
    {货号}
    Prn_Text_TrueType(g, e+f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AZ'), pchar('货号:'+edtNo.Text ));
    {型号}
    Prn_Text_TrueType(g, e+2*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('ZA'), pchar('型号:'+cboType.Text ));
    {价格}
    Prn_Text_TrueType(g, e+3*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AB'), pchar('价格:'+edtPrice.text+'.00'));
    {面料}
    Prn_Text_TrueType(g, e+4*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AC'), pchar('面料:'+edtMaterial1.Text+'%'+cboMaterial1.Text  ));
    if edtMaterial2.text<>'' then
    Prn_Text_TrueType(105, e+5*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AD'), pchar(edtMaterial2.text+'%'+cboMaterial2.Text));
    if edtMaterial3.text<>'' then
    Prn_Text_TrueType(105, e+6*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('AE'), pchar(edtMaterial3.text+'%'+cboMaterial3.Text));
    if edtMaterial4.text<>'' then
    Prn_Text_TrueType(105, e+7*f, h, pchar('仿宋_GB2312'), 1, 400, 0, 0, 0, pchar('EA'), pchar(edtMaterial4.text+'%'+cboMaterial4.Text));

#5


这是一个打印软件的一部分,希望对你能有帮助!

#6


记得在Delphi3的时候Windows单元里没有AnimateWindow
我当时是这样声明的!
function AnimateWindow(hWnd: HWND; dwTime: DWORD; dwFlags: DWORD): BOOL; stdcall;external user32 name 'AnimateWindow';

#7


DELPHI 中动态链接库的使用 
作者:  评价:  上站日期: 2001-05-09  
内容说明:  
来源:  

--------------------------------------------------------------------------------

  在DELPHI中,有两种方法可用于调用一个储存在DLL(动态链接库)中的过程。 

一、 调用方法 

1、 静态调用或显式装载使用一个外部声明子句,使DLL在应用程序开始执行前即被装入。例如: 

Function instring (sourcestr: Pchar ;
check: char): integer; far; external ‘ demostr’
这种方式要在单元的interface 部分用external 指示字列出要从DLL中调用的例程。Far 指令表明可以被其他段,例如其他单元调用的子例程。所有在单元接口中声明的子例程在缺省情况下都是Far类型的,其相反的指令是near。 

如果external 后什么也不跟,必须用 {$ L } 编译指令预先指定一个DLL名字,如: 

{ $ L Mydlls.dll }
Procedure setstring(var str: string) ;
stdcall ; external
但是使用静态调用方法时,程序无法在运行时间里决定DLL的调用。在DELPHI中使用DLL时,例程的标识符必须与DLL中相应输出例程的标识符完全一致(尽管DELPHI本身大小写不敏感)。 

2、 动态调用或隐式装入 

使用WINDOWS API 函数 Loadlibrary 和GetprocAddress可以实现在运行时间里的动态装载DLL,并调用其中的过程。 

例如: 

      Type TMyProc=Procedure (Param:Pchar ) ;Stdcall;
      Var MyProc: TMyproc;
       MyHandle:THandle;
       MyHandle:=LoadLibrary (‘Mydll’) ;
       If MyHandle<  =0 then
        Raise Exception.Create
        ( ‘动态链接库调用失败,错误代码
        是:’+Inttostr(Getlasterror))
        else 
         @MyProc:=GetProcAddress(MyHandle,’demoproc’);
       if not Assigned(MyProc) then
        Raise Exception.Create('GetProcAddress 
        调用失败,错误代码
           是:’+inttostr(getlasterror))
        else MyProc(Pchar(‘a string’));
        Freelibrary(Myhandle); // 卸载DLL
二、 调用方式 

1、 通过过程、函数名; 

2、 通过过程、函数别名; 

3、 通过过程、函数的顺序号 

例:Function Getstring : string ; stdcall ; external ‘Mydlls.dll’ name ‘Mygetstr’name 子句指定函数名Getstring 改为Mygetstr,当程序调用这个例程时,使用Mygetstr这个名字;Function Getstring : string ; stdcall ; external ‘Mydlls.dll’ index 5 Index 子句通过索引号引入例程可以减少DLL的加载时间。 

三、 调用约定 

调用约定,是指调用例程时参数的传递顺序。DELPHI中DLL支持的调用约定有: 

调用约定 参数传递顺序
Register 从左到右
Pascal 从左到右
Stdcall 从右到左
Cdecl 从右到左
Safecall 从右到左
使用Stdcall 方式,能保证不同语言写的DLL的兼容性,同时它也是WINDOWS API的约定方式;Delphi 3。0、4。0的默认调用方式为Register ;Cdecl是采用 C/C++的调用约定,适用于DLL是由C++语言编写的;Safecall 是适合于声明OLE对象中的方法。 

四、 DLL中的变量和段 

一个DLL声明的任何变量都为自己私有 ,调用它的模块不能直接使用它定义的变量。要使用时必须通过过程或函数界面才能完成,对DLL来说,它永远都没有机会使用调用它的模块中的声明的变量。一个DLL没有自己的SS(堆栈段),它使用调用它的应用程序的堆栈。因此在DLL中的过程、函数不要假定DS=SS(DS为数据段)。 

 
 

#8


#9


#10


to  CSDNBowlder:这些代码好熟系哦,请问你现在在哪里呢?可以认识一下吗?

#11


procedure TForm1.Button1Click(Sender: TObject);
type
  TQTSetAppHandle = procedure(Value: THandle); stdcall;
  TQTExecute = procedure; stdcall;
var
  LibHandle: THandle;
  QTSetAppHandle: TQTSetAppHandle;
  QTExecute: TQTExecute;
begin
  LibHandle := LoadLibrary('lockscr');
  if LibHandle <> 0 then
  begin

    @QTSetAppHandle := GetProcAddress(LibHandle, 'QTSetAppHandle');
    if @QTSetAppHandle <> nil then QTSetAppHandle(Application.Handle);

    @QTExecute := GetProcAddress(LibHandle , 'QTExecute');
    if @QTExecute <> nil then
    begin
      Application.Minimize;
      Application.ProcessMessages;
      QTExecute;
    end;
    FreeLibrary(LibHandle);
  end;
end;