什么时候可以用到函数指针?

时间:2022-04-06 13:53:52
函数指针到底用在哪些地方,什么时候要用到函数指针?
即函数指针的应用
请举例。谢谢!

9 个解决方案

#1


典型的函数指针
BOOL EnumWindows(

    WNDENUMPROC lpEnumFunc, // pointer to callback function
    LPARAM lParam  // application-defined value
   );

#2


***************
**为红星而努力**
***************

函数指针:

在动态调用DLL中的函数时,就会用到函数指针。假设用C写的一段
代码如下:
    typedef int (*PVFN)(int); //定义函数指针类型
    int main() 
    {
      HMODULE hModule = LoadLibrary("test.dll");
      PVFN pvfn = NULL;
      pvfn = (PVFN) GetProcAddress(hModule, "Function1");
      pvfn(2);
      FreeLibrary(hModule);
    }
    就我个人感觉来说,C语言中定义函数指针类型的typedef代码的语法有些晦涩,
而同样的代码在 Object Pascal中却非常易懂:
    type PVFN = Function (para : Integer) : Integer;
    var fn : PVFN; 
      //也可以直接在此处定义,如:fn : function (para:Integer):Integer;
      hm : HMODULE;
    begin
      hm := LoadLibrary('test.dll');
      fn := GetProcAddress(hm, 'Function1');
      fn(2);
      FreeLibrary(hm);
    end;

#3


在 FontDialog 的 FontApply 事件中,也就是点 FontDialog 的 Apply 按钮时,需要处理这个按钮的代码就需要写一段函数,然后将这个函数的地址(也可以理解为函数指针)传送给 FontDialog 。

#4


很多的,特别是winapi函数和调用dll时用得最多

#5


在动态调用 DLL 中的函数时 ,就会用到函数指针。假设用 C 写的一段代码如下 :

typedef int (*PVFN)(int); // 定义函数指针类型 

int main()

{

HMODULE hModule = LoadLibrary("test.dll");

PVFN pvfn = NULL;

pvfn = (PVFN) GetProcAddress(hModule, "Function1");

pvfn(2);

FreeLibrary(hModule);

}

就我个人感觉来说 ,C 语言中定义函数指针类型的 typedef 代码的语法有些晦涩 ,而同样的代码在 

Object Pascal 中却非常易懂 :

type PVFN = Function (para : Integer) : Integer;

var

fn : PVFN;

// 也可以直接在此处定义 ,如 :fn : function (para:Integer):Integer;

hm : HMODULE;

begin

hm := LoadLibrary('test.dll');

fn := GetProcAddress(hm, 'Function1');

fn(2);

FreeLibrary(hm);

end;

#6


FUNCTION POINTER 
This is what I came up with when building a simple states machine:

This is a very simple example of using function pointers under Borland Delphi to control program flow.  Just create a simple form with one button and add the code from Unit1 to the unit created.  Add Unit2
to the project and compile.  Give me a yell if you have any problems.

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  CurrProc : LongInt;
  MyVal : LongInt;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  NewProc : LongInt;
  MyString : string;
begin
  CurrProc := 2;                { beginning point in proc table }
  MyVal := 0;                   { dummy variable }
  NewProc := 0;                 { return value for next index in proc
table }
  while CurrProc < 6 do
    begin
    { execute the current index in the proc table and get the next proc
}
    NewProc := ProcTable[CurrProc](MyVal);

    { this is just to track the values of NewProc and CurrProc }
    FmtStr(MyString, 'NewProc [%d]  CurrProc [%d]', [NewProc,
CurrProc]);
    MessageDlg(MyString, mtInformation, [mbOK], 0);

    { set the current proc to the returned proc }
    CurrProc := NewProc;
    end;

end;

end.

{ This is a simple example of defining an array of function pointers }

interface

type
  { define Procs as a function }
  Procs = function(var ProcNum : LongInt): LongInt;

var
  { declare the array of function pointers }
  ProcTable : Array [1..5] of Procs;

{ function interface definitions }
function Proc1(var MyVal : LongInt) : LongInt; far;
function Proc2(var MyVal : LongInt) : LongInt; far;
function Proc3(var MyVal : LongInt) : LongInt; far;
function Proc4(var MyVal : LongInt) : LongInt; far;
function Proc5(var MyVal : LongInt) : LongInt; far;


implementation

uses Dialogs;

function Proc1(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 1', mtInformation, [mbOK], 0);
  Proc1 := 6;
end;

function Proc2(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 2', mtInformation, [mbOK], 0);
  Proc2 := 3;
end;

function Proc3(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 3', mtInformation, [mbOK], 0);
  Proc3 := 4;
end;

function Proc4(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 4', mtInformation, [mbOK], 0);
  Proc4 := 5;
end;

function Proc5(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 5', mtInformation, [mbOK], 0);
  Proc5 := 1;
end;

initialization

  { initialize the contents of the array of function pointers }
  @ProcTable[1] := @Proc1;
  @ProcTable[2] := @Proc2;
  @ProcTable[3] := @Proc3;
  @ProcTable[4] := @Proc4;
  @ProcTable[5] := @Proc5;

end.

I think I would do something like this: Declare in each form procedures that handle the buttonpresses, like procedure CutButtonPressed(Sender:TObject) of Object; Then I would simply assign the buttons'  OnClick events to these procedures in the forms OnActivate event. This would be the oop way to do it, but if you don't like it, I think Delphi still has function pointers.

Define a base class form with an abstract function declaration for each of the functions you want to call from your toolbar. Then derive each of your forms from that base class form, and provide definitions for those functions.

Eg: (There might be a couple of syntax errors here - I haven't compiled it)
type
  TBaseForm = class(TForm)
  public
    procedure Method1; virtual; abstract;
end;

type
  TDerivedForm1= class(TBaseForm)
  public
    procedure Method1; override;
  end;

  TDerivedForm2= class(TBaseForm)
  public
    procedure Method1; override;
  end;

  procedure TDerivedForm1.Method1;
  begin
    ....
  end;

  procedure TDerivedForm2.Method1;
  begin
    ....
  end;

{To call the function from your toolbar, get
the currently active form and call Method1}
procedure OnButtonClick;
var
  AForm: TBaseForm;
begin
  AForm := ActiveForm as TBaseForm;
  AForm.Method1;
end

#7


无论任何时候你都在使用!!!!!!!!

#8


最典型的是回调函数!

#9


楼上把我的话先说了

#1


典型的函数指针
BOOL EnumWindows(

    WNDENUMPROC lpEnumFunc, // pointer to callback function
    LPARAM lParam  // application-defined value
   );

#2


***************
**为红星而努力**
***************

函数指针:

在动态调用DLL中的函数时,就会用到函数指针。假设用C写的一段
代码如下:
    typedef int (*PVFN)(int); //定义函数指针类型
    int main() 
    {
      HMODULE hModule = LoadLibrary("test.dll");
      PVFN pvfn = NULL;
      pvfn = (PVFN) GetProcAddress(hModule, "Function1");
      pvfn(2);
      FreeLibrary(hModule);
    }
    就我个人感觉来说,C语言中定义函数指针类型的typedef代码的语法有些晦涩,
而同样的代码在 Object Pascal中却非常易懂:
    type PVFN = Function (para : Integer) : Integer;
    var fn : PVFN; 
      //也可以直接在此处定义,如:fn : function (para:Integer):Integer;
      hm : HMODULE;
    begin
      hm := LoadLibrary('test.dll');
      fn := GetProcAddress(hm, 'Function1');
      fn(2);
      FreeLibrary(hm);
    end;

#3


在 FontDialog 的 FontApply 事件中,也就是点 FontDialog 的 Apply 按钮时,需要处理这个按钮的代码就需要写一段函数,然后将这个函数的地址(也可以理解为函数指针)传送给 FontDialog 。

#4


很多的,特别是winapi函数和调用dll时用得最多

#5


在动态调用 DLL 中的函数时 ,就会用到函数指针。假设用 C 写的一段代码如下 :

typedef int (*PVFN)(int); // 定义函数指针类型 

int main()

{

HMODULE hModule = LoadLibrary("test.dll");

PVFN pvfn = NULL;

pvfn = (PVFN) GetProcAddress(hModule, "Function1");

pvfn(2);

FreeLibrary(hModule);

}

就我个人感觉来说 ,C 语言中定义函数指针类型的 typedef 代码的语法有些晦涩 ,而同样的代码在 

Object Pascal 中却非常易懂 :

type PVFN = Function (para : Integer) : Integer;

var

fn : PVFN;

// 也可以直接在此处定义 ,如 :fn : function (para:Integer):Integer;

hm : HMODULE;

begin

hm := LoadLibrary('test.dll');

fn := GetProcAddress(hm, 'Function1');

fn(2);

FreeLibrary(hm);

end;

#6


FUNCTION POINTER 
This is what I came up with when building a simple states machine:

This is a very simple example of using function pointers under Borland Delphi to control program flow.  Just create a simple form with one button and add the code from Unit1 to the unit created.  Add Unit2
to the project and compile.  Give me a yell if you have any problems.

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  CurrProc : LongInt;
  MyVal : LongInt;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  NewProc : LongInt;
  MyString : string;
begin
  CurrProc := 2;                { beginning point in proc table }
  MyVal := 0;                   { dummy variable }
  NewProc := 0;                 { return value for next index in proc
table }
  while CurrProc < 6 do
    begin
    { execute the current index in the proc table and get the next proc
}
    NewProc := ProcTable[CurrProc](MyVal);

    { this is just to track the values of NewProc and CurrProc }
    FmtStr(MyString, 'NewProc [%d]  CurrProc [%d]', [NewProc,
CurrProc]);
    MessageDlg(MyString, mtInformation, [mbOK], 0);

    { set the current proc to the returned proc }
    CurrProc := NewProc;
    end;

end;

end.

{ This is a simple example of defining an array of function pointers }

interface

type
  { define Procs as a function }
  Procs = function(var ProcNum : LongInt): LongInt;

var
  { declare the array of function pointers }
  ProcTable : Array [1..5] of Procs;

{ function interface definitions }
function Proc1(var MyVal : LongInt) : LongInt; far;
function Proc2(var MyVal : LongInt) : LongInt; far;
function Proc3(var MyVal : LongInt) : LongInt; far;
function Proc4(var MyVal : LongInt) : LongInt; far;
function Proc5(var MyVal : LongInt) : LongInt; far;


implementation

uses Dialogs;

function Proc1(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 1', mtInformation, [mbOK], 0);
  Proc1 := 6;
end;

function Proc2(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 2', mtInformation, [mbOK], 0);
  Proc2 := 3;
end;

function Proc3(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 3', mtInformation, [mbOK], 0);
  Proc3 := 4;
end;

function Proc4(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 4', mtInformation, [mbOK], 0);
  Proc4 := 5;
end;

function Proc5(var MyVal : LongInt) : LongInt;
begin
  MessageDlg('Proc 5', mtInformation, [mbOK], 0);
  Proc5 := 1;
end;

initialization

  { initialize the contents of the array of function pointers }
  @ProcTable[1] := @Proc1;
  @ProcTable[2] := @Proc2;
  @ProcTable[3] := @Proc3;
  @ProcTable[4] := @Proc4;
  @ProcTable[5] := @Proc5;

end.

I think I would do something like this: Declare in each form procedures that handle the buttonpresses, like procedure CutButtonPressed(Sender:TObject) of Object; Then I would simply assign the buttons'  OnClick events to these procedures in the forms OnActivate event. This would be the oop way to do it, but if you don't like it, I think Delphi still has function pointers.

Define a base class form with an abstract function declaration for each of the functions you want to call from your toolbar. Then derive each of your forms from that base class form, and provide definitions for those functions.

Eg: (There might be a couple of syntax errors here - I haven't compiled it)
type
  TBaseForm = class(TForm)
  public
    procedure Method1; virtual; abstract;
end;

type
  TDerivedForm1= class(TBaseForm)
  public
    procedure Method1; override;
  end;

  TDerivedForm2= class(TBaseForm)
  public
    procedure Method1; override;
  end;

  procedure TDerivedForm1.Method1;
  begin
    ....
  end;

  procedure TDerivedForm2.Method1;
  begin
    ....
  end;

{To call the function from your toolbar, get
the currently active form and call Method1}
procedure OnButtonClick;
var
  AForm: TBaseForm;
begin
  AForm := ActiveForm as TBaseForm;
  AForm.Method1;
end

#7


无论任何时候你都在使用!!!!!!!!

#8


最典型的是回调函数!

#9


楼上把我的话先说了