运用CAR智能指针实现Callback机制
- 格式:pdf
- 大小:383.49 KB
- 文档页数:5
c语言callback回调函数C语言的回调函数是一种非常重要的编程技术,它可以实现程序的灵活性和可扩展性,同时也可以提高代码的重用性和可维护性。
本文将详细介绍C语言的回调函数,包括定义、用法、实现原理以及常见应用等方面。
一、回调函数的定义回调函数是指在一个函数中调用另一个函数,并将其作为参数传递给调用函数的一种技术。
在C语言中,回调函数通常是指一个函数指针,它指向一个函数,并可以作为参数传递给另一个函数。
回调函数的定义格式如下:```返回值类型 (*函数名)(参数列表);```其中,返回值类型是指回调函数返回的值的类型,函数名是指回调函数的名称,参数列表是指回调函数接收的参数列表。
例如,下面是一个简单的回调函数定义示例:```int (*callback)(int, int);```这个回调函数的返回值类型为int,函数名为callback,参数列表包括两个int类型的参数。
二、回调函数的用法回调函数主要用于实现程序的动态扩展和灵活性。
它可以使程序在运行时根据需要动态地调用指定的函数,而不必在编译时就确定执行的函数。
这种灵活性使得回调函数在很多编程场景中都得到了广泛应用。
例如,在GUI编程中,回调函数通常用于响应用户的操作,例如单击按钮、拖动窗口等事件。
程序可以根据用户的操作动态地调用相应的回调函数,从而实现交互式的界面效果。
在网络编程中,回调函数也经常被用于处理异步操作,例如网络连接、数据接收等操作。
程序可以将回调函数作为参数传递给异步操作函数,当异步操作完成时,程序会自动调用相应的回调函数,从而实现对异步操作的处理。
三、回调函数的实现原理回调函数的实现原理是基于函数指针的机制。
在C语言中,函数名就是一个指向函数体的指针,它可以被赋值给另一个指向函数的指针变量。
回调函数的本质就是将一个函数的指针作为参数传递给另一个函数,并在需要时调用该函数指针所指向的函数。
例如,下面是一个简单的回调函数示例:```int add(int a, int b) {return a + b;}int sub(int a, int b) {return a - b;}int calc(int a, int b, int (*callback)(int, int)) {return callback(a, b);}int main() {int a = 10, b = 5;printf("add: %d\n", calc(a, b, add));printf("sub: %d\n", calc(a, b, sub));return 0;}```这个程序定义了两个函数add和sub,它们分别实现了加法和减法运算。
call back的用法Call back 的用法回调函数是一种常见的编程技术,它在编程语言中被广泛使用,尤其在事件驱动的编程中。
回调函数(callback function)是一个指向函数的指针,它传递给一个函数,并在特定事件发生时被调用。
这篇文章将详细介绍回调函数的用法,并提供一些示例帮助读者理解。
首先,回调函数是如何工作的呢?在许多编程语言中,函数可以作为参数传递给其他函数。
当某个事件触发时,这个函数可以作为回调函数被调用。
换句话说,回调函数是由另一个函数调用的函数,它可以返回一个值或执行一系列操作。
为了更好地理解回调函数的用法,让我们以JavaScript为例。
在JavaScript 中,回调函数常用于处理异步操作。
异步操作是指在某个任务完成之前代码可以继续执行,而不必等待任务的完成。
这在处理网络请求或读取大文件时非常有用,避免了阻塞线程。
假设我们要编写一个函数,从服务器获取用户的个人信息并在页面上显示。
由于网络请求是异步的,我们无法立即获取用户信息。
这时,我们可以使用回调函数来处理这个异步操作。
首先,我们定义一个函数getUserInfo,它接受一个回调函数作为参数:javascriptfunction getUserInfo(callback) {模拟从服务器获取用户信息的异步操作setTimeout(function() {const userInfo = { name: "John", age: 25 };callback(userInfo);}, 1000); 假设请求需要1秒钟返回结果}在这个示例中,我们使用setTimeout模拟异步操作,1秒钟后调用回调函数,并将获取到的用户信息作为参数传入。
现在,我们可以在回调函数中处理这个数据:javascriptfunction displayUserInfo(userInfo) {console.log("Name:", );console.log("Age:", userInfo.age);}getUserInfo(displayUserInfo);在上面的代码中,我们定义了一个回调函数displayUserInfo,它接受一个参数userInfo,并在控制台上显示用户的姓名和年龄。
智能指针weakptr原理
智能指针是C++中用于管理动态内存的一种工具,它可以帮助
程序员避免内存泄漏和悬空指针等问题。
智能指针中的weak_ptr是
一种特殊的智能指针,它用于解决shared_ptr的循环引用问题。
weak_ptr是一种弱引用,它允许你观察shared_ptr指向的对象,但并不拥有对象的所有权。
当最后一个shared_ptr指向的对象
被销毁时,即使还有weak_ptr指向该对象,weak_ptr也会自动失效,避免悬空指针的问题。
weak_ptr的实现原理涉及到引用计数。
当我们使用shared_ptr 时,每个指向对象的shared_ptr都会维护一个引用计数,记录有多
少个shared_ptr指向该对象。
而weak_ptr则不会增加引用计数,
它只是观察shared_ptr的引用计数。
当对象的引用计数变为0时,
对象会被销毁,这时所有指向该对象的weak_ptr都会自动失效。
另外,为了确保在使用weak_ptr时不会访问已经被销毁的对象,我们可以通过调用weak_ptr的lock()方法来获得一个指向对象的shared_ptr,如果对象还存在的话。
通过这种方式,我们可以安全
地访问对象,而不用担心对象已经被销毁。
总的来说,weak_ptr通过观察shared_ptr的引用计数,避免循环引用导致的内存泄漏问题,同时提供了一种安全的方式来访问被shared_ptr管理的对象。
这种设计在C++中的动态内存管理中起到了非常重要的作用。
call back的用法-回复Call back的用法Call back(回调)是一种编程技术,它允许异步操作在完成后通知调用方。
回调函数是在另一个函数执行完成后被调用的函数。
在这篇文章中,我们将一步一步地探讨call back的用法,以及它在编程中的实际应用。
首先,为了理解call back的概念,我们需要先了解异步编程。
在传统的同步编程中,代码按顺序执行,直到前面的代码完成后才能执行后面的代码。
然而,在某些情况下,我们可能需要执行一些耗时的操作,如发送网络请求或读取文件,这会导致程序在等待结果返回时被阻塞。
异步编程的目标是在等待结果返回的同时,让程序继续执行其他任务,以提高效率。
在异步编程中,调用方通常不会等待操作完成,并且可能在操作完成之前继续执行其他代码。
这就是回调的用武之地。
通过使用回调函数,我们可以将需要在操作完成后执行的代码传递给操作本身,以便在操作完成后调用。
接下来,让我们看一个简单的例子来理解call back的用法。
假设我们正在开发一个网络爬虫,我们需要从一个网站上获取数据。
由于网络请求是一个耗时的操作,我们希望程序在等待结果返回的同时能够执行其他任务。
这就是我们可以使用回调函数的地方。
我们首先定义一个函数来执行网络请求:function makeRequest(url, callback) {执行网络请求在请求完成后调用回调函数callback(response);}在上面的代码中,makeRequest函数接受一个url和一个回调函数作为参数。
它执行网络请求后,在请求完成后调用回调函数,并将得到的响应作为参数传递给回调函数。
接下来,我们可以定义一个回调函数来处理网络请求的结果:function handleResponse(response) {处理响应数据console.log(response);}在这个简单的例子中,我们将回调函数handleResponse传递给makeRequest函数。
lua不定参数处理摘要:1.Lua 中不定参数处理的需求2.Lua 中的可变参数列表3.使用元表和泛型函数处理不定参数正文:在Lua 编程语言中,我们经常会遇到需要处理不定数量参数的情况。
例如,在编写一个函数时,我们可能需要接收任意数量的输入参数。
为了解决这个问题,Lua 提供了一种处理不定参数的方式,即可变参数列表。
可变参数列表是Lua 中一种特殊的参数类型,它允许函数在调用时接收任意数量的参数。
在函数定义时,我们可以在参数类型前加上一个省略号(...),表示该参数是一个可变参数列表。
例如:```function sum(...args)local result = 0for i, arg in ipairs(args) doresult = result + argendreturn resultend```在这个例子中,我们定义了一个名为`sum`的函数,它接收一个可变参数列表`args`。
在函数内部,我们使用`ipairs`函数遍历参数列表,并将每个元素累加到`result`变量中。
最后,返回累加的结果。
然而,在使用可变参数列表时,我们无法直接知道传递给函数的参数个数。
为了解决这个问题,我们可以使用元表和泛型函数。
元表是Lua 中的一种特殊数据结构,它可以存储关于其他表的信息。
通过元表,我们可以知道一个表的行数、列数以及每个元素的类型等信息。
我们可以使用元表来获取可变参数列表的长度。
泛型函数是Lua 中一种可以处理任意类型参数的函数。
通过使用泛型函数,我们可以在编译时检查函数参数的类型,并在运行时根据实际参数类型进行相应的处理。
结合元表和泛型函数,我们可以编写一个处理不定参数的函数。
例如:```local function sum_generic(func,...args)local meta = metatable(args)local num_args = meta.nlocal result = func(args)return resultendlocal function sum(x)return xendlocal result = sum_generic(sum, 1, 2, 3)print(result) -- 输出:6```在这个例子中,我们定义了一个名为`sum_generic`的泛型函数,它接收一个函数`func`和一个可变参数列表`args`。
c++智能指针的工作原理
C++智能指针是一种用于管理动态分配的内存的工具。
它们可
以自动进行内存管理,以避免内存泄漏和重复释放的问题。
C++标准库中提供了两种智能指针:std::shared_ptr和
std::unique_ptr。
1. std::shared_ptr:
- 智能指针使用引用计数的方法来管理内存。
它们会记录有
多少个智能指针指向同一块内存。
- 当创建一个std::shared_ptr时,引用计数初始化为1。
- 每次复制或移动std::shared_ptr时,引用计数会递增。
- 当智能指针超出其作用域或被重新分配时,引用计数会递减。
- 当引用计数变为0时,智能指针会自动销毁所管理的内存。
2. std::unique_ptr:
- 智能指针使用独占所有权的方法来管理内存。
它们不允许
多个指针同时指向相同的内存。
- 当创建一个std::unique_ptr时,它会获取对所管理的内存的
独占所有权。
- std::unique_ptr不支持复制,只能通过移动来传递所有权。
- 当智能指针超出其作用域时,它会自动销毁所管理的内存。
无论是std::shared_ptr还是std::unique_ptr,当智能指针超出其
作用域或被重新分配时,它们所管理的内存都会被自动释放。
这样可以避免手动释放内存、内存泄漏和重复释放的问题,提高了代码的可靠性和可维护性。
C++中智能指针的设计和使用/hackbuteer1/article/details/7561235智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露。
它的一种通用实现技术是使用引用计数(reference count)。
智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。
每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
智能指针就是模拟指针动作的类。
所有的智能指针都会重载-> 和* 操作符。
智能指针还有许多其他功能,比较有用的是自动销毁。
这主要是利用栈对象的有限作用域以及临时对象(有限作用域实现)析构函数释放内存。
当然,智能指针还不止这些,还包括复制时可以修改源对象等。
智能指针根据需求不同,设计也不同(写时复制,赋值即释放对象拥有权限、引用计数等,控制权转移等)。
auto_ptr 即是一种常见的智能指针。
智能指针通常用类模板实现:[cpp] view plaincopy1template <class T>2class smartpointer3{4private:5 T *_ptr;6public:7 smartpointer(T *p) : _ptr(p) //构造函数8 {9 }10 T& operator *() //重载*操作符11 {12return *_ptr;13 }14 T* operator ->() //重载->操作符15 {16return _ptr;17 }18 ~smartpointer() //析构函数19 {20delete _ptr;21 }22};实现引用计数有两种经典策略,在这里将使用其中一种,这里所用的方法中,需要定义一个单独的具体类用以封装引用计数和相关指针:23// 定义仅由HasPtr类使用的U_Ptr类,用于封装使用计数和相关指针24// 这个类的所有成员都是private,我们不希望普通用户使用U_Ptr类,所以它没有任何public成员25// 将HasPtr类设置为友元,使其成员可以访问U_Ptr的成员26class U_Ptr27{28friend class HasPtr;29int *ip;30size_t use;31 U_Ptr(int *p) : ip(p) , use(1)32 {33 cout << "U_ptr constructor called !" << endl;34 }35 ~U_Ptr()36 {37delete ip;38 cout << "U_ptr distructor called !" << endl;39 }40};条件就是引用计数。
callback 解析-回复Callback 解析Callback函数是一种常见的编程概念,被广泛应用于各种编程语言和框架中。
在本篇文章中,我们将一步一步回答关于Callback解析的问题,深入探讨它的概念以及在实际应用中的用途和优势。
一、Callback是什么?Callback是一种函数或方法的引用,可以作为参数传递给其他函数或方法。
当某个特定事件发生或满足某个条件时,这个传递的函数将会被调用。
Callback函数可以根据需要执行一系列操作,通常用于处理异步任务、事件处理、错误处理等。
二、Callback的工作原理是什么?在程序中,Callback函数被传递给另一个函数作为参数,并在需要的时候被调用。
当某个特定事件发生时,主函数会调用Callback函数执行特定的操作。
这种方式可以实现灵活的异步编程,避免了直接等待异步操作结果的情况,提高了程序的效率和性能。
三、Callback的优势是什么?1. 异步编程:Callback函数允许在异步任务完成后执行特定操作。
它能够优化程序的效率,确保任务能够在不阻塞主线程的情况下进行。
2. 可重用性:Callback函数可以在多个地方使用,提高了代码的可重用性。
我们可以将具有相同或相似功能的Callback函数用于不同的场景,并避免代码的重复编写。
3. 条件触发:使用Callback函数,我们可以根据不同的条件来触发特定的操作。
这使得代码可以根据运行时的不同情况做出相应的响应,并实现更加灵活的程序逻辑。
四、Callback的典型应用场景有哪些?1. 异步编程:在JavaScript中,Callback函数经常用于处理异步任务,如定时器、网络请求等。
通过传递Callback函数作为参数来处理响应事件,可以确保任务的正确执行顺序和相应的处理。
2. 事件处理:在图形用户界面(GUI)和Web开发中,Callback函数常用于处理用户的交互事件。
当用户执行某个操作时,Callback函数会被调用,用于更新界面、处理数据等操作。
callback使用方法Callback使用方法在编程中,callback(回调)是一种常见的技术,它允许我们在某个任务完成后,通过调用一个函数来处理结果。
在本文中,我将介绍callback的使用方法,并通过实例来说明它的应用。
一、什么是callback?Callback是一种异步编程的技术,它允许我们在执行某个任务后,通过调用一个函数来处理结果。
这种方式可以有效地避免阻塞主线程的问题,提高程序的效率和响应速度。
二、如何使用callback?1. 定义一个callback函数:我们需要定义一个函数作为callback。
这个函数将在任务完成时被调用,并接收任务的结果作为参数。
2. 将callback作为参数传递:接下来,我们需要找到一个适合的任务或函数,并将定义的callback作为参数传递给它。
这样,在任务完成时,就会调用我们定义的callback函数。
3. 处理任务结果:在callback函数中,我们可以根据任务的结果进行相应的处理。
例如,可以打印结果、保存到数据库或执行其他操作。
三、callback的实例应用下面,我将通过一个实例来说明callback的应用。
假设我们需要从一个网站上获取用户信息,并将其保存到数据库中。
首先,我们可以编写一个函数来获取用户信息:```function getUserInfo(callback) {// 模拟从网站上获取用户信息的过程const userInfo = {name: '小明',age: 20,gender: '男'};// 任务完成后,调用callback函数处理结果callback(userInfo);}```然后,我们可以定义一个callback函数来处理用户信息:```function saveUserInfo(userInfo) {// 将用户信息保存到数据库中// ...console.log('用户信息已保存到数据库');}```接下来,我们调用`getUserInfo`函数,并将`saveUserInfo`作为callback传递进去:```getUserInfo(saveUserInfo);```当`getUserInfo`函数完成任务后,会调用`saveUserInfo`函数,并将获取到的用户信息作为参数传递给它。
c语言callback函数解释说明1. 引言1.1 概述callback函数是一种在C语言中经常使用的编程技术,它允许我们将一个函数作为参数传递给另一个函数,并且在特定的条件满足时被调用。
这种机制使得代码更加模块化和灵活,提高了程序的可扩展性和复用性。
1.2 文章结构本文将介绍callback函数的定义、作用以及使用场景。
我们将详细探讨callback 函数的实现原理,包括函数指针和回调函数参数传递,以及回调函数的注册和调用流程。
同时,我们还会给出一个处理异步任务示例来说明如何使用callback 函数。
此外,文章还将分享一些有关编写callback函数的技巧和注意事项,例如命名规范、参数类型和返回值定义方式选择等。
最后,在结论部分对整个话题进行总结。
1.3 目的本文旨在帮助读者深入理解callback函数,并掌握其在C语言编程中的应用。
通过阅读本文,读者将了解到什么是callback函数以及它们能够实现什么样的功能。
此外,我们还希望读者能够学习到如何正确地实现和使用callback函数,并避免一些可能出现的问题。
最终,读者将能够更加熟练地运用callback函数来解决实际问题,提高自己的编程能力。
2. callback函数的定义和作用2.1 callback函数的概念Callback函数是一种特殊类型的函数,它允许我们将一个函数作为参数传递给另一个函数。
通常情况下,callback函数会在某个特定条件或事件发生后被调用执行。
这种机制使得我们能够以灵活的方式进行代码复用和扩展,并且可以实现异步操作、事件处理等功能。
2.2 callback函数的作用callback函数具有以下几个主要作用:1. 代码复用:通过将一些通用功能封装成callback函数,可以在不同场景下进行重复利用。
例如,在图形界面编程中,我们可以创建一个通用的按钮点击事件callback函数,并在需要时传入不同的处理逻辑。
2. 异步操作:callback函数经常被用于处理异步操作,例如文件读写、网络请求等。
收稿日期:2007-05-31基金项目:国家“863”计划资助项目(2001AA113400)作者简介:叶 蓉(1980-),女,江苏南京人,硕士研究生,研究方向为嵌入式操作系统、系统软件支撑技术;陈 榕,教授,博士生导师,研究方向为嵌入式系统、构件技术。
运用CAR 智能指针实现C allb ack 机制叶 蓉1,2,陈 榕1(1.同济大学基础软件工程中心,上海200092;2.上海第二工业大学,上海201209)摘 要:“和欣”操作系统是基于CAR 构件技术、支持构件化应用的嵌入式操作系统。
一般的构件,客户与构件之间的通信过程是单向的,客户创建构件对象,然后客户调用对象所提供的接口函数。
在这样的通讯过程中,客户总是主动的,而构件对象则处于被动状态。
对于一个全面的交互过程来说,这样的单向通信往往不能满足实际的需要,构件对象也要主动与客户进行通信,构件也提供回调接口。
和欣系统中的Callback 机制有助于实现二进制构件拼装;并允许构件异地运行,可极大地提高构件的运行效率,但其本身实施过程很复杂。
提出在“和欣”操作系统中,实现CAR 智能指针来简化用户实现Callback 机制的过程。
关键词:CAR ;CAR 智能指针;Callback 机制中图分类号:TP311 文献标识码:A 文章编号:1673-629X (2008)02-0009-04Using CAR Smart Pointer to R ealize C allback MechanismYE Rong 1,2,CHEN Rong 1(1.System S oftware Engineering Centre of Tongji University ,Shanghai 200092,China ;2.Shanghai Second Polytechnic University ,Shanghai 201209,China )Abstract :Elastos operating system ,which can sustain component applications ,is based on component assembly runtime 2munication process between normal component and client is one -way oriented ,client builds component object ,and then calls interface provided by the object.In this communication process ,the client is always active ,and component object is in a passive state.For a com 2prehensive interactive process ,such one -way communication often cannot meet the actual needs ,component object also need take the initiative to communicate with client ,as well as to provide call back interface.Elastos Callback mechanism is helpful for binary compo 2nents ’integration and it allows components running in different context ,which largely improves the CAR component running efficiency.However the normal Callback implementation is too much complicated during execution.Depicts how to use CAR smart pointer to sim 2plize the application procedure of Callback mechanism.K ey w ords :component assembly runtime ;CAR smart pointer ;Callback mechanism0 引 言基于构件的软件工程是实现高生产率、低维护费用和高可靠软件产品的关键技术。
构件的使用方式类似于“客户/服务器”模型,其中构件充当服务器的角色。
一般的构件,客户与构件之间的通信过程是单向的,客户创建构件对象,然后客户调用对象所提供的接口函数。
在这样的通讯过程中,客户总是主动的,而构件对象则处于被动状态。
对于一个全面的构件交互过程来说,这样的单向通信往往不能满足实际的需要,有时候构件对象也要主动与客户进行通信,因此,与普通接口(interface ,也称为入接口)相对应,构件也可以提供回调接口(icallback ,也称为出接口),对象通过回调接口与客户进行通信。
Callback 机制有助于实现二进制构件拼装;并允许构件异地运行。
极大地提高了构件的运行效率,但Callback 机制实施过程很复杂,因此采用类智能指针包装其交互过程来简化用户使用的复杂性。
文中提出在CAR 构件技术中运用智能指针对客户端进行简化,以方便用户使用CAR 构件。
用户可以通过宏定义选择直接通过接口指针进行操作,亦可以选择通过智能指针完成对接口的使用。
CAR 的智能第18卷 第2期2008年2月 计算机技术与发展COMPU TER TECHNOLO GY AND DEV ELOPMEN T Vol.18 No.2Feb. 2008指针可以向用户屏蔽了对构件生命周期的管理,用户使用智能指针,无需再去考虑繁琐复杂的AddRef 、Re 2lease 的调用,简化了编程的步骤,降低编程难度,同时确保客户能正确地控制构件的生命周期,提高了用户应用程序的安全性,降低了资源泄漏的可能;通过智能指针能够检查接口的类型安全性,消除潜在的错误。
1 “和欣”操作系统和CAR 构件编程环境1.1 “和欣”操作系统“和欣”[1]操作系统是863计划的“基于中间件技术的因特网嵌入式操作系统及跨操作系统中间件运行平台”的重要成果,是一个基于构件的灵活内核现代操作系统。
“和欣”操作系统与宏内核或微内核操作系统的最大区别就是其将微内核模型与基于构件技术的充分结合,形成了“和欣”操作系统的灵活内核架构模型。
1.2 CAR 构件程序集运行时CAR (Component Assembly Runtime )是国内拥有自主知识产权的先进构件系统。
CAR 构件技术定义了一套网络编程时代的构件编程模型和编程规范,它规定了一组构件间相互调用的标准,使得二进制构件能够自描述,能够在运行时动态链接。
CAR 构件技术继承了COM [2,3]的二进制封装思想,面向接口编程。
在逐步融合.Net 、Java 技术思想之后,形成独有的二进制构件程序模型。
CAR 构件技术采用C ++编程,使用和欣SD K 提供的工具直接生成运行于和欣构件运行平台的二进制代码。
因此CAR 构件机制使得程序员能够充分运用自己熟悉的编程语言知识和开发经验,很容易掌握面向构件、中间件编程的技术。
2 用智能指针实现CAR 回调机制2.1 回调机制构件模块之间总是存在着一定的接口,从调用方式上,可以分为三类:同步调用、回调和异步调用。
同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知被调用方(即调用被调用方的接口)。
回调和异步调用的关系非常紧密,通常使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。
同步调用是三者当中最简单的,而回调又常常是异步调用的基础。
具体来说,回调如图1所示,就是模块A 调用模块B ,而模块B 中要调用模块A 中的函数C 的代码,其中函数C 就是回调函数;图1 回调机制的实现客户端(模块A 地址空间)首先通过同步方式调用服务端(模块B 地址空间)的注册接口来注册回调接口,服务端收到该请求以后,就会保留该接口引用,如果发生某种事件需要向客户端通知的时候就通过该引用调用客户方的回调函数,以便对方及时处理。
在CAR 的回调机制中,有一种接收器(sink )对象,接收器对象相当于一个客户端回调函数的容器,在客户端的地址空间里,负责与可连接对象进行通信。
只要有可连接对象存在,那么在客户端肯定要有接收器的存在。
多个回调接口可对应一个接收器对象,这样可以减少通信花费的开销。
当接收器与可连接对象建立连接后,客户程序可将自己实现的事件处理函数(回调函数)向接收器进行注册,而不是向可连接对象进行图2 CAR 回调机制具体实现・01・ 计算机技术与发展 第18卷注册,又一次减少了通信开销。
接收器会自动把在它里面注册的函数的回调接口指针告诉构件对象,构件对象在条件成熟时激发事件,如果客户注册了自己的回调接口方法,那么就会被调用,否则就调用接收器默认实现的回调接口方法。
其过程如图2所示。
在编写构件程序时,用户需定义何时激发事件,在编写客户端程序时,用户需在适当的时候注册事件处理函数。
其它的工作,如接收器对象的实现、接收器与可连接对象建立通信的具体过程、事件的分发回调过程等都由CAR 实现。
2.2 未采用CAR 智能指针实现回调(C allback)机制未使用CAR 智能指针的回调(Callback )过程如图3所示。
图3 未使用CAR 智能指针的Callback 机制实现从图中可以看出,Callback 机制实施过程比较复杂,用户需自行创建可连接对象以及接收器,并在接收器中注册对应的回调事件,回调事件触发后,用户还需要向接收器对象注销对应的回调事件,并断开与可连接对象的连接。
这一系列过程本身比较复杂,不易于用户的使用。
由此,提出采用CAR 智能指针为用户封装Callback 机制的细节,方便用户的使用。
2.3 CAR 智能指针实现回调(C allback)机制通过CAR 智能指针简化用户实现Callback 机制的过程如图4所示。
对比图3和图4可以看出,CAR 构件技术提供智能指针对客户端进行简化,以方便用户使用CAR 构件。
图4 使用CAR 智能指针的Callback 机制实现CAR 的智能指针向用户屏蔽了对构件回调事件的处理,用户无需再去考虑繁琐复杂的初始化及注册过程,简化了编程的步骤,降低编程难度,同时CAR 的智能指针确保客户能正确地控制构件的生命周期,提高了用户应用程序的安全性,降低了资源泄漏的可能;通过智能指针能够检查接口的类型安全性,消除潜在的错误。