Delphi 函数指针(三大好处:灵活,委托的本质,回调机制),还可把函数指针当参数传入
首先学习: 指向非对象(一般的)函数/过程的函数指针
Pascal 中的过程类型与C语言中的函数指针相似,为了统一说法,以下称函数指针。函数指针的声明只需要参数列表;如果是函数,再加个返回值。例如声明一个过程类型,该类型带一个通过引用传递的整型参数:
type
IntProc = procedure (var Num: Integer);
这个过程类型与任何参数完全相同的例程兼容,即用它声明的变量,可以指向任何此类函数,并通过其进行函数的调用。下面是一个兼容例程:
procedure DoubleTheValue (var Value: Integer);
begin
Value := Value * 2;
end;
函数指针能用于两种不同的目的:声明函数指针类型的变量;或者把函数指针作为参数传递给另一例程。利用上面给定的类型和过程声明,你可以写出下面的代码:
var
IP: IntProc;
X: Integer;
begin
IP := DoubleTheValue;
X := 5;
IP (X);
end;
虽然这种调用方法比直接调用麻烦了,那么我们为什么要用这种方式呢?
(1)因为在某些情况下,调用什么样的函数需要在实际中(运行时)决定,你可以根据条件来判断,实现用同一个表达,调用不同的函数,很是灵活.
(2)利用函数指针我们可以实现委托,委托在.NET中被发挥的淋漓尽致,但Delphi同样能实现
(3)实现回调机制
函数指针很有用啊,是高级程序员的必修。
例子
- {********************************************************
- 函数指针(指向一般函数和过程)
- UnitOwner:coco.zhang
- Last Modified:2008-10-5
- *********************************************************}
- unit DelegateUnit;
- interface
- procedure Func1;
- {定义两个函数型构相同但功能不同的函数}
- function FuncAdd(VarA , VarB : Integer):Integer;
- function FuncSub(VarA , VarB : Integer):Integer;
- type
- DelegateFunc1 = procedure;
- DelegateFuncCalc = function(VarA , VarB : Integer):Integer;
- var
- I : Integer;
- implementation
- procedure Func1;
- begin
- Writeln('Func1 was called!');
- end;
- function FuncAdd(VarA , VarB : Integer):Integer;
- begin
- Result := VarA + VarB;
- end;
- function FuncSub(VarA , VarB : Integer):Integer;
- begin
- Result := VarA - VarB;
- end;
- end.
客户端调用
- program Delegate;
- {$APPTYPE CONSOLE}
- uses
- DelegateUnit;
- var
- ADelegateFunc1 : DelegateFunc1;
- ADelegateFuncCalc : DelegateFuncCalc;
- begin
- {通过函数指针调用过程}
- ADelegateFunc1 := Func1;
- ADelegateFunc1 ;
- {通过同种方式调用不同函数}
- ADelegateFuncCalc := FuncAdd;
- Writeln(ADelegateFuncCalc(3,5));
- ADelegateFuncCalc := FuncSub;
- Writeln(ADelegateFuncCalc(3,5));
- end.
Func1 was called!
8
-2
Delphi函数指针的使用
geek_loser 发布于 1年前,共有 0 条评论
delphi中可以通过函数指针把一个函数作为参数来传递,然后在另外一个函数中调用。
1) 首先,申明函数指针类型TFunctionParameter。
type
TFunctionParameter = function(const value : integer) : string;
2) 定义准备被作为参数传递的函数
function One(const value : integer) : string;
begin
result := IntToStr(value) ;
end;
function Two(const value : integer) : string;
begin
result := IntToStr(2 * value) ;
end;
3) 定义将要使用动态函数指针参数的函数
function DynamicFunction(f : TFunctionParameter; const value : integer) : string;
begin
result := f(value) ;
end;
4) 上面这个动态函数的使用实例
var
s : string;
begin
s := DynamicFunction(One,2006) ;
ShowMessage(s) ; //will display "2006"
s := DynamicFunction(Two,2006) ;
ShowMessage(s) ; // will display "4012"
end;
一个指向函数的指针在赋值指向函数时,不需要显示地取函数的地址。
例:
var F:function(X:Integer):Integer;
...
function aa(X:Integer):Integer;
不需要: F:=^aa;
只要:F:=aa;就可以了。
F:=aa可能是一个函数类型变量赋值,也可能是调用aa函数过程。
如果F不是一个函数过程类型,它就是一个函数调用。
但是只要是出现在表达式中,就一定是函数过程的调用。
例:if A:=fun then
A:=fun一定是一个函数过程的调用,将返回值赋予A
注意,如果fun是一个过程(它没有返回值)或它需要参数(需要写上参数),那就会产生语法错误。
如果要显示说明它是一个赋值语句而不是函数过程的调用,可以这样写
@A是将A转换成一个无类型指针(它本身就是以指针形式存在)
@fun是取得函数过程fun的地址
可以通过@@A的方式取得该过程函数变量的地址,而不是它指向的函数过程的地址
void SetProcessDataProc(NOTISFYDATAISRECEIVED ProcessDataProc)
参数:ProcessDataProc —— 回调函数指针。
返回值:无
功能:设置数据到达通知函数。动态连接库主动通知用户有新数据到达,随后用户就可以立即查询相关数据。用户调用此接口函数设置通知函数以后,每当新数据到达,动态连接库就通过这个通知函数通知用户。通知函数原型必须如下:(函数名称和参数名称可以不同)
void ProcessDataProc(int iBedNo,unsigned char ucDataType,WPARAM wParam);
其中,iBedNo参数表示到达数据所对应的设备号。
ucDataType表示到达数据类型。ucDataType值与对应的数据包类型以及常调用的接口函数如表1所示。对于表中没有列举的数据包类型,数据包内没有有用的数据。
wParam用于传递其他信息,保留,暂时没有使用。
所以,SetProcessDataProc接口函数的参数类型NOTISFYDATAISRECEIVED可以定义如下:
typedef void(* NOTISFYDATAISRECEIVED)(int iBedNo,unsigned char ucDataType,WPARAM wParam);
这是一个动态连接库中一个函数,我现在想在delphi中调用该函数,请问该如何定义上述类型和函数。
void ProcessDataProc(int iBedNo,unsigned char ucDataType,WPARAM wParam);
->
procedure ProcessDataProc(iBedNo: Integer; ucDataType:BYTE; wParam: WPARAM);stdcall;
typedef void(* NOTISFYDATAISRECEIVED)(int iBedNo,unsigned char ucDataType,WPARAM wParam);
->
type NOTISFYDATAISRECEIVED = procedure of(iBedNo: Integer; ucDataType:BYTE; wParam: WPARAM) of object;///
Delphi 函数指针(三大好处:灵活,委托的本质,回调机制),还可把函数指针当参数传入的更多相关文章
- 成员函数指针与高效C++委托 (delegate)
下载实例源代码 - 18.5 Kb 下载开发包库文件 - 18.6 Kb 概要 很遗憾, C++ 标准中没能提供面向对象的函数指针. 面向对象的函数指针也被称为闭包(closures) 或委托(del ...
- 成员函数指针与高性能C++委托
1 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做“闭包(closure)”或“委托(delegate)”)在一些语言中已经证明了它宝贵的价值. ...
- C#编程语言之委托与事件(一)—— C/C++函数指针和C#委托初步
相信正在学习C#的人都有学习过C或C++的经验,本文要讲的第一个要点是C#中的委托(delegate,有些资料也叫代表).什么是委托,很多人都能自然而然地想到C/C++中的函数指针,事实上很多书和资料 ...
- selector函数指针回调机制
selector可以叫做选择器,其实指的就是对象的方法,也可以理解为C语言里面的函数指针,在面向对象里面的对应概念. [self performSelector:@selector(Hidden) w ...
- Delphi的DateToStr StrToDate格式灵活用法
Delphi的DateToStr StrToDate格式灵活用法 2008-04-09 10:19 procedure TForm1.Button1Click(Sender: TObject);var ...
- “XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
症状描述如下: 如果将一个委托作为函数指针从托管代码封送到非托管代码,并且在对该委托进行垃圾回收后对该函数指针发出了一个回调,则将激活 callbackOnCollectedDelegate 托管调试 ...
- DATEADD和DATEDIFF函数、其他日期处理方法 、已打开的端口、FORMAT函数
DATEADD和DATEDIFF函数.其他日期处理方法 .已打开的端口.FORMAT函数 DATEADD和DATEDIFF函数.其他日期处理方法 .已打开的端口.Format函数 KeyLife富翁笔 ...
- c# “XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
症状描述如下: 如果将一个委托作为函数指针从托管代码封送到非托管代码,并且在对该委托进行垃圾回收后对该函数指针发出了一个回调,则将激活 callbackOnCollectedDelegate 托管调试 ...
- BMDP为常规的统计分析提供了大量的完备的函数系统,如:方差分析(ANOVA)、回归分析(Regression)、非参数分析(Nonparametric Analysis)、时间序列(Times Series)等等。此外,BMDP特别擅于进行出色的生存分析(Survival Analysis )。许多年来,一大批世界范围内顶级的统计学家都曾今参与过BMDP的开发工作。这不仅使得BMDP的权威性得到
BMDP是Bio Medical Data Processing的缩写,是世界级的统计工具软件,至今已经有40多年的历史.目前在国际上与SAS.SPSS被并称为三大统计软件包.BMDP是一个大 ...
随机推荐
- 矩阵乘法的MPI并行计算
1.问题描述 矩阵乘法问题描述如下: 给定矩阵A和B,其中A是m*p大小矩阵,B是p*n大小的矩阵.求C = A*B. 求解这个问题最简单的算法是遍历A的行和B的列,求得C的相应元素,时间复杂度O(m ...
- spring+hibernate
添加注解时spring是添加在set方法上而hibernate是添加在get方法上 事务应该加在service层上,而不是加在dao层上,如果加在dao层上回滚的时候只能回滚一个dao的实现. 事务处 ...
- linux初学(CentOS)之注意事项(一)
linux严格区分大小写(命令,文件名,用户名等) linux所有内容以文件形式保存,包括硬件 硬盘文件是/dev/sd[a-p](a,p为盘符名) 光盘文件是/dev/sr0等 linux不靠扩展名 ...
- ASP.NET页面继承关系
用过ASP.NET(以下简称ASP)的都知道ASP以一种Code Behind的方式给咱展现了一种类似Winform的开发模型,同样也是以"事件触发"的方式进行各种请求处理.其中A ...
- 【转】vs2010下创建webservice
题记:学了六个月java一直想做java,没想到进了.NET项目组,还是VB2012,还有WebService,压力山大,这篇纯粹看看多图的效果,版主不要怪罪. Visual Studio 2010默 ...
- 推荐大家使用的CSS书写规范、顺序(转载)
转自:http://www.admin10000.com/document/2979.html 写了这么久的CSS,但大部分前端er都没有按照良好的CSS书写规范来写CSS代码,这样会影响代码的阅读体 ...
- Oracle EBS-SQL (BOM-11):检查无BOM的装配件.sql
select msi.segment1, msi.description, . msi.item_type, msi.inventory_item_status_code 状态 from ...
- Android Studio下载安装及配置图文教程
原文 http://jingyan.baidu.com/article/9c69d48f56835e13c9024e95.html AndroidStudio下载地址:https://develope ...
- POJ 1556 计算几何+最短路
代码1: #include<iostream> #include<stdio.h> #include<string> #include<string.h> ...
- 【带权并查集】【HDU3038】【How Many Answers Are Wrong】d s
这个题看了2天!!!最后看到这篇题解才有所明悟 转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298091.html ---by 墨染之樱 ...