Delphi與dll中使用回呼函數示例......... interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; type PFCALLBACK = function(Param1:integer;Param2:integer):integer;stdcall; // 定義回呼函數的類型 var Form1: TForm1; gCallBack:PFCALLBACK; function CBFunc(Param1:integer;Param2:integer):integer;stdcall; implementation //回呼函數需要定義為全域 {$R *.dfm} ///實現回呼函數的功能 function CBFunc(Param1:integer;Param2:integer):integer; var i:integer; begin //messagebox(application.Handle,'回呼函數','提示資訊',mb_ok); for i:=0 to 100 do begin sleep(100); self.ListBox1.Items.Add('回呼函數'); end; end; /// function MyThreadFunc(P:pointer):Longint;stdcall; begin gCallBack(0,1);//簡單傳個參數 end; procedure testpro ; var i:integer; hThread:Thandle;//定義一個控制碼 ThreadID:DWord; begin for i:=0 to 4 do begin messagebox(application.Handle,'123','提示資訊',mb_ok); if (i=2) then begin hthread:=CreateThread(nil,0,@MyThreadfunc,nil,0,ThreadID);//利用這種執行緒怎麼說呢,肯定方便啦,但是 //肯定功能上受到好多限制,所以啊,自己寫,下次貼個上來 end; end; end; /// function TestCallBack( Func:PFCALLBACK ):integer; begin gCallBack:=Func; testpro; end; procedure TForm1.Button1Click(Sender: TObject); begin //testpro; TestCallBack(@CBFunc); end; procedure TForm1.Button2Click(Sender: TObject); begin self.ListBox1.Clear; end; end. 使用回呼函數需要注意的地方: type PFCALLBACK = function(Param1:integer;Param2:integer):integer;stdcall; // 定義回呼函數的類型 function CBFunc(Param1:integer;Param2:integer):integer;stdcall; //全域函式定義,指向函數的函數,指標!!!名字可以隨便取,但參數之類的需要與定義 //的函數類型一致。 function CBFunc(Param1:integer;Param2:integer):integer; //寫該函數體就沒什麼好說拉 function TestCallBack( Func:PFCALLBACK ):integer; //傳遞回呼函數的入口地址,最重要啦!
什麼也不說了,我直接上代碼 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type THDProcedure=procedure(s:string); stdcall; Tfsdajk = function (RecvBack:THDProcedure):integer;StdCall; TForm1 = class(TForm) Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; DLLHandle:THandle; procedure HdProExample(sExam:string);stdcall; implementation {$R *.dfm} procedure HdProExample(sExam:string);stdcall; begin ShowMessage(sExam); end; procedure TForm1.FormCreate(Sender: TObject); begin DLLHandle := LoadLibrary(PChar('Project.dll')); end; procedure TForm1.Button2Click(Sender: TObject); var D: String; Func: Tfsdajk; begin @Func := GetProcAddress(DLLHandle, 'loadDllA'); if Assigned(@Func) then begin Func(@HdProExample); end; end; end. dll部分: library Project; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses SysUtils, Classes; type THDProcedure=procedure(s:string); stdcall; var fsda : THDProcedure; {$R *.res} function loadDllA(RecvBack:THDProcedure):integer;StdCall; begin @fsda := @RecvBack; fsda(PChar('fdasfd')); end; exports loadDllA Name 'loadDllA'; begin end. 如果想在主程序中的“HdProExample”使用主程序中的方法的話要加表單名哦例如: procedure HdProExample(sExam:string);stdcall; begin Form1.ExeSQL(sExam);//我傳回來的是SQL語句所以我用到了Fom1中的ExeSQL。 end;
interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls; type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type PFCALLBACK = function(Param1:integer;Param2:integer):integer;stdcall;
// 定義回呼函數的類型
var
Form1: TForm1;
gCallBack:PFCALLBACK;
function CBFunc(Param1:integer;Param2:integer):integer;stdcall;
implementation
//回呼函數需要定義為全域
{$R *.dfm}
///實現回呼函數的功能
function CBFunc(Param1:integer;Param2:integer):integer;
var i:integer;
begin
//messagebox(application.Handle,'回呼函數','提示資訊',mb_ok);
for i:=0 to 100 do
begin
sleep(100);
self.ListBox1.Items.Add('回呼函數');
end;
end;
///
function MyThreadFunc(P:pointer):Longint;stdcall;
begin
gCallBack(0,1);//簡單傳個參數
end;
procedure testpro ;
var i:integer;
hThread:Thandle;//定義一個控制碼
ThreadID:DWord;
begin
for i:=0 to 4 do
begin
messagebox(application.Handle,'123','提示資訊',mb_ok);
if (i=2) then
begin
hthread:=CreateThread(nil,0,@MyThreadfunc,nil,0,ThreadID);//利用這種執行緒怎麼說呢,肯定方便啦,但是
//肯定功能上受到好多限制,所以啊,自己寫,下次貼個上來
end;
end;
end;
///
function TestCallBack( Func:PFCALLBACK ):integer;
begin
gCallBack:=Func;
testpro;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//testpro;
TestCallBack(@CBFunc);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
self.ListBox1.Clear;
end;
end.
使用回呼函數需要注意的地方:
type PFCALLBACK = function(Param1:integer;Param2:integer):integer;stdcall;
// 定義回呼函數的類型
function CBFunc(Param1:integer;Param2:integer):integer;stdcall;
//全域函式定義,指向函數的函數,指標!!!名字可以隨便取,但參數之類的需要與定義
//的函數類型一致。
function CBFunc(Param1:integer;Param2:integer):integer;
//寫該函數體就沒什麼好說拉
function TestCallBack( Func:PFCALLBACK ):integer;
//傳遞回呼函數的入口地址,最重要啦!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
THDProcedure=procedure(s:string); stdcall;
Tfsdajk = function (RecvBack:THDProcedure):integer;StdCall;
TForm1 = class(TForm)
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
DLLHandle:THandle;
procedure HdProExample(sExam:string);stdcall;
implementation
{$R *.dfm}
procedure HdProExample(sExam:string);stdcall;
begin
ShowMessage(sExam);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DLLHandle := LoadLibrary(PChar('Project.dll'));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
D: String;
Func: Tfsdajk;
begin
@Func := GetProcAddress(DLLHandle, 'loadDllA');
if Assigned(@Func) then
begin
Func(@HdProExample);
end;
end;
end.
dll部分:
library Project;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
SysUtils,
Classes;
type
THDProcedure=procedure(s:string); stdcall;
var
fsda : THDProcedure;
{$R *.res}
function loadDllA(RecvBack:THDProcedure):integer;StdCall;
begin
@fsda := @RecvBack;
fsda(PChar('fdasfd'));
end;
exports
loadDllA Name 'loadDllA';
begin
end.
如果想在主程序中的“HdProExample”使用主程序中的方法的話要加表單名哦例如:
procedure HdProExample(sExam:string);stdcall;
begin
Form1.ExeSQL(sExam);//我傳回來的是SQL語句所以我用到了Fom1中的ExeSQL。
end;