MSDN中回调函数的讲解及其C#例子:用委托实现回调函数
转自:http://blog.csdn.net/sizheng0320/article/details/1615777
ms-help://MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconusingcallbackfunctions.htm
回调函数是托管应用程序中可帮助非托管 DLL 函数完成任务的代码。对回调函数的调用将从托管应用程序中,通过一个 DLL 函数,间接地传递给托管实现。在用平台调用调用的多种 DLL 函数中,有些函数要求正确地运行托管代码中的回调函数。本主题将介绍托管函数的元素,并说明如何实现回调函数和从托管代码中调用回调函数。
回调函数基础
要从托管代码中调用大多数 DLL 函数,可创建该函数的托管定义,然后调用该函数。此过程比较直接。
要使用需要回调函数的 DLL 函数,则会有一些附加的步骤。首先,必须在文档中查阅该函数,确定该函数是否需要回调。接着,必须在托管应用程序中创建回调函数。最后,调用该 DLL 函数,并将指向回调函数的指针当作参数进行传递。下图总结了这些步骤。
回调函数和实现

回调函数非常适合在重复执行任务的情况下使用。另一个常见用途是与枚举函数(如 Win32 API 中的EnumFontFamilies、EnumPrinters 和 EnumWindows)一起使用。如下一节中的示例所示,EnumWindows 函数将枚举计算机上的所有现有窗口,并调用回调函数来对每个窗口执行一项任务。

实现回调函数
以下过程将说明托管应用程序如何使用平台调用来输出本地计算机上每个窗口的句柄值。尤其是,示例将使用EnumWindows 函数来逐步浏览窗口列表,并使用一个托管回调函数(名为 CallBack)来输出窗口句柄的值。
实现回调函数
- 开始实现之前,先查看 EnumWindows 函数的签名。EnumWindows 具有以下签名:
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
表示此函数需要回调的线索之一是存在 lpEnumFunc 参数。如果参数采用指向回调函数的指针,其名称中通常会有 lp(长指针)前缀与 Func 后缀的组合。有关 Win32 函数的文档,请参见 Microsoft Platform SDK。
- 创建托管回调函数。该示例声明一个名为
CallBack的委托类型,此委托类型采用两个参数:hwnd 和lparam。第一个参数是窗口的句柄;第二个参数由应用程序定义。在此版本中,这两个参数都必须是整数。回调函数通常会返回非零值来表示成功,返回零来表示失败。本示例将返回值显式设置为 true,以继续进行枚举。
- 创建一个委托,并将其作为参数传递给 EnumWindows 函数。平台调用会自动将委托转换为常见的回调格式。
- 确保在回调函数完成其工作之前,垃圾回收器不会回收委托。如果委托作为参数进行传递,或者所包含的委托作为结构中的字段进行传递,则该委托在调用期间不会被回收。因此,正如下面的枚举示例所示,回调函数会在调用返回前完成其工作,而无需托管调用方执行额外的操作。
然而,如果可以在调用返回后调用回调函数,则托管调用方必须采取相应的措施来确保委托在回调函数完成其工作之前不会被回收。有关防止垃圾回收的详细信息,请参见用平台调用进行 Interop 封送处理。
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace MyDelegate
{
#region 委托实现回调函数
public delegate bool CallBack(int hwnd, int lParam);
public class EnumReportApp
{
[DllImport("user32")]
//user32.dll中的Win32函数原型为:
//BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
//表示此函数需要回调的线索之一是存在 lpEnumFunc 参数。如果参数采用指向回调函数的指针,其名称中通常会有 lp(长指针)前缀与 Func 后缀的组合。
//这里在导入user32.dll后,引入该函数,但是已经将其第一个参数传入了这里定义的委托函数CallBack
public static extern int EnumWindows(CallBack x, int y);
public static bool Report(int hwnd, int lParam)
{
Console.Write("Window handle is ");
Console.WriteLine(hwnd);
return true;
}
public static void Main()
{
//实例化一个委托,其实现为上面定义的Report,即调用myCallBack时就是调用了Report
CallBack myCallBack = new CallBack(EnumReportApp.Report);
//从这个.NET程序中调用外面user32.dll中的Win32的函数,但是该函数“向回调用(回调)”刚刚定义的.NET程序中的函数myCallBack
EnumWindows(myCallBack, 0);
Console.ReadLine();
}
}
#endregion
}
MSDN中回调函数的讲解及其C#例子:用委托实现回调函数的更多相关文章
- Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!
开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...
- 在 ASP.NET 网页中不经过回发而以编程方式实现客户端回调
在 ASP.NET 网页的默认模型中,用户会与页交互,单击按钮或执行导致回发的一些其他操作.此时将重新创建页及其控件,并在服务器上运行页代码,且新版本的页被呈现到浏览器.但是,在有些情况下,需要从客户 ...
- 选择列表中的列……无效,因为该列没有包含在聚合函数或 GROUP BY 子句中
今天用SQL Server尝试实现一个SQL语句的时候,报了如标题所示的错误,通过在百度里面搜索,并亲自动手实现,终于发现问题所在,现在把它记录下来. 语句如下: select [OrderID],[ ...
- Mysql学习总结(5)——MySql常用函数大全讲解
MySQL数据库中提供了很丰富的函数.MySQL函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操作.例如,字符串连接函数 ...
- python format函数/print 函数详细讲解(4)
在python开发过程中,print函数和format函数使用场景特别多,下面分别详细讲解两个函数的用法. 一.print函数 print翻译为中文指打印,在python中能直接输出到控制台,我们可以 ...
- MySQL常用函数大全讲解
MySQL数据库中提供了很丰富的函数.MySQL函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操作.例如,字符串连接函数 ...
- (转)浅析epoll – epoll函数深入讲解
原文地址:http://www.cppfans.org/1418.html 浅析epoll – epoll函数深入讲解 前一篇大致讲了一下epoll是个什么东西,优点等内容,这篇延续上一篇的内容,主要 ...
- webdriver中的等待——主要讲解WebDriverWait()
webdriver中的等待--主要讲解WebDriverWait() 强制等待:sleep() 隐式等待:implicitly_wait() 显示等待:WebDriverWait() 与until() ...
- 嵌入式&iOS:回调函数(C)与block(OC)回调对比
学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...
随机推荐
- Linux CentOS 7 安装字体库 & 中文字体
前言 报表中发现有中文乱码和中文字体不整齐(重叠)的情况,首先考虑的就是操作系统是否有中文字体,在CentOS 7中发现输入命令查看字体列表是提示命令无效: 如上图可以看出,不仅没有中文字体,连字体库 ...
- CSS之position体验
目录: 1. position介绍 2. relative 3. position 4. fixed与static 5. 总结 1. position介绍 position最简单的理解就是元素位置的定 ...
- Django 2.0 的路由如何实现正则表达式
在django2.0的路由系统中,摒弃了1.x中的url,而改用path.需要导入path. from django.urls import path,re_path 在1.x中,使用url()即可实 ...
- 服务器22端口连接超时 ssh: connect to host *** port 22: Operation timed out
最近酸酸乳出问题,连接v社服务器发现碰到 ssh: connect to host master port 22: Connection timed out 的问题.现在对该问题做一下可能出现的问题 ...
- js Math对象的常用方法
1,基本方法: Math.round();向上四舍五入. Math.ceil();向上取整,有小数就整数部分加1 Math.floor(5/2) ;向下取整 Math.abs();返回绝对值: Mat ...
- H3C Huawei 交换机 IPv6环境配置
# 使能IPv6报文转发功能. <Sysname> system-view [Sysname] ipv6 # 使能DHCPv6服务器功能. <Sysname> system-v ...
- ansible 调用playbook api执行(一)
一 调用ansible playbook api执行playbook 1 准备好hosts文件 root@ansible:~/ansible/playbooks# cat hosts [all:var ...
- HtmlHelper.Raw,<%%>,<%:%>,<%=%>的区别及使用
Mvc中<%%>,<%:%>,<%=%>的区别及使用 1.<%%> <%%>之间可以执行服务端代码,如<% foreach (Data ...
- ajaxFileUpload的data数据带pre标签
解决办法: var ret = jQuery.parseJSON(jQuery(data).text());
- jq的attr、prop和data区别
prop()获取在匹配的元素集中的第一个元素的属性值. 大家都知道有的浏览器只要写disabled,checked就可以了,而有的要写成disabled = "disabled", ...