宏的使用方式

下面举例记录宏的一种使用方式。

##name  用来在宏定义中传递名称变量。

由于宏定义仅直接插入调用处,可以用来进行函数声明

4.1 interface_cast

[-> IInterface.h]

1 template<typename INTERFACE>
2 inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
3 {
4     return INTERFACE::asInterface(obj); //【见小节4.2】
5 }

这是一个模板函数,可得出,interface_cast<IServiceManager>() 等价于 IServiceManager::asInterface()。接下来,再来说说asInterface()函数的具体功能。

4.2 IServiceManager::asInterface

对于asInterface()函数,通过搜索代码,你会发现根本找不到这个方法是在哪里定义这个函数的, 其实是通过模板函数来定义的,通过下面两个代码完成的:

1 //位于IServiceManager.h文件 【见小节4.3】
2 DECLARE_META_INTERFACE(ServiceManager)
3 //位于IServiceManager.cpp文件 【见小节4.4】
4 IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager")

接下来,再说说这两行代码分别完成的功能:

4.3 DECLARE_META_INTERFACE

[-> IInterface.h]

1 #define DECLARE_META_INTERFACE(INTERFACE)                               2     static const android::String16 descriptor;                          3     static android::sp<I##INTERFACE> asInterface(                       4             const android::sp<android::IBinder>& obj);                  5     virtual const android::String16& getInterfaceDescriptor() const;    6     I##INTERFACE();                                                     7     virtual ~I##INTERFACE();                                            \

位于IServiceManager.h文件中,INTERFACE=ServiceManager展开即可得:

[-> IServiceManager.h]

1 static const android::String16 descriptor;
2
3 static android::sp< IServiceManager > asInterface(const android::sp<android::IBinder>& obj)
4
5 virtual const android::String16& getInterfaceDescriptor() const;
6
7 IServiceManager ();
8 virtual ~IServiceManager();

该过程主要是声明asInterface(),getInterfaceDescriptor()方法.

4.4 IMPLEMENT_META_INTERFACE

[-> IInterface.h]

 1 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                        2     const android::String16 I##INTERFACE::descriptor(NAME);              3     const android::String16&                                             4             I##INTERFACE::getInterfaceDescriptor() const {               5         return I##INTERFACE::descriptor;                                 6     }                                                                    7     android::sp<I##INTERFACE> I##INTERFACE::asInterface(                 8             const android::sp<android::IBinder>& obj)                    9     {                                                                   10         android::sp<I##INTERFACE> intr;                                 11         if (obj != NULL) {                                              12             intr = static_cast<I##INTERFACE*>(                          13                 obj->queryLocalInterface(                               14                         I##INTERFACE::descriptor).get());               15             if (intr == NULL) {                                         16                 intr = new Bp##INTERFACE(obj);                          17             }                                                           18         }                                                               19         return intr;                                                    20     }                                                                   21     I##INTERFACE::I##INTERFACE() { }                                    22     I##INTERFACE::~I##INTERFACE() { }                                   \

位于IServiceManager.cpp文件中,INTERFACE=ServiceManager, NAME=”android.os.IServiceManager”展开即可得:

[-> IServiceManager.cpp]

 1 const android::String16 IServiceManager::descriptor(“android.os.IServiceManager”);
 2
 3 const android::String16& IServiceManager::getInterfaceDescriptor() const
 4 {
 5      return IServiceManager::descriptor;
 6 }
 7
 8  android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
 9 {
10        android::sp<IServiceManager> intr;
11         if(obj != NULL) {
12            intr = static_cast<IServiceManager *>(
13                obj->queryLocalInterface(IServiceManager::descriptor).get());
14            if (intr == NULL) {
15                intr = new BpServiceManager(obj);  //【见小节4.5】
16             }
17         }
18        return intr;
19 }
20
21 IServiceManager::IServiceManager () { }
22 IServiceManager::~ IServiceManager() { }

不难发现,[小节4.2]的IServiceManager::asInterface() 等价于 new BpServiceManager()。在这里,更确切地说应该是new BpServiceManager(BpBinder)。

5.1

Native层的Binder架构,通过如下两个宏,非常方便地创建了new Bp##INTERFACE(obj):

1 //用于申明asInterface(),getInterfaceDescriptor()
2 #define DECLARE_META_INTERFACE(INTERFACE)
3 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) //用于实现上述两个方法

例如:

1 // 实现BPServiceManager对象
2 IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager")

等价于:

 1 const android::String16 IServiceManager::descriptor(“android.os.IServiceManager”);
 2 const android::String16& IServiceManager::getInterfaceDescriptor() const
 3 {
 4      return IServiceManager::descriptor;
 5 }
 6
 7  android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
 8 {
 9        android::sp<IServiceManager> intr;
10         if(obj != NULL) {
11            intr = static_cast<IServiceManager *>(
12                obj->queryLocalInterface(IServiceManager::descriptor).get());
13            if (intr == NULL) {
14                intr = new BpServiceManager(obj);
15             }
16         }
17        return intr;
18 }
19
20 IServiceManager::IServiceManager () { }
21 IServiceManager::~ IServiceManager() { }
时间: 2024-10-06 18:50:37

宏的使用方式的相关文章

typedef 类型重命名 和 #define 宏定义(1)

http://www.blogjava.net/jasmine214--love/archive/2010/11/29/339307.html 在现实生活中,信息的概念可能是长度,数量和面积等.在C语言中,信息被抽象为int.float和double等基本数据类型.从基本数据类型名称上, 不能够看出其所代表的物理属性,并且int.float和double为系统关键字,不可以修改.为了解决用户自定义数据类型名称的需求,C语言中引入类 型重定义语句typedef,可以为数据类型定义新的类型名称,从而

vim 宏的使用

1. 基本使用 q[a-z] 开始录制宏 q  停止录制 @[a-z] 使用宏 @@ 调用最近使用的宏 [email protected][a-z] 多次重放宏 2. 宏的执行方式 串行方式:[email protected][a-z] 宏内包含向下一个目标行进行移动的指令,如果出现错误,宏会停止执行 并行方式::normal @[a-z] 在高亮区域的每一行上并行执行宏,某一行出现错误不影响其他行

inline函数与宏定义

本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4975474.html 今天我在优化公司项目代码的过程中,借助了Intel的VTune工具查看热点函数,发现有一个名为GetMatrixKey的函数调用频率很高,这个函数的主要作用是从一个矩阵数组中获取Matrix,其中还包含了指针检查与数组越界检查.考虑到这个函数的功能很简单,我就把它的实现挪到了头文件,并加上了inline关键字.随后我查看了一下这个函数的调用,发现它只在下面这个

Objective-C枚举的几种定义方式与使用

假设我们需要表示网络连接状态,可以用下列枚举表示: enum CSConnectionState { CSConnectionStateDisconnected, CSConnectionStateConnecting, CSConnectionStateConnected, }; 然而定义枚举变量的方式却太不简介,要依如些语法编写: enum CSConnectionState state = CSConnectionStateDisconnected; 若是每次不用敲入 enum 而只需写

Verilog中parameter(参数)与define(宏定义)的区别

语句格式 parameter xx=yy; (有分号) ’define xx yy   (无分号) 作用范围 参数是局部的,只在其定义的模块内部起作用,而宏定义对同时编译的多个文件起作用.即使在某一个模块内部指定的宏定义,在编译过程中仍旧对多个文件起作用,直至遇到重新定义为止. 状态机环境下 状态机的定义可以用parameter 定义,但是不推荐使用`define 宏定义的方式,因为'define 宏定义在编译时自动替换整个设计中所定义的宏,而parameter 仅仅定义模块内部的参数,定义的参

[转]高速掌握VC6.0中各种宏注释(附图)

为了方便别人或自己阅读自己的程序,注释是坚决不可少的.一个漂亮的程序,不是在于你应用的技术多么高深,而是能够把高深的技术描述的清楚易懂. 在Java的IDE环境——Eclispe中,有很多中注释的,并且设置注释也是很方便的,因为现在从事C++,嘻嘻,Eclispe已经卸载,至于设置注释的地方,直接百度或谷歌即可. 所以嘛,习惯了Eclispe的注释,所以想法设法,在VC6.0中尝试.当对于一个陌生的东西而言,如何熟悉他呢,就是拿你现在已有的知识,去联想.比如Java中截取字符串,或解析xml等,

sas宏(3)宏,调试宏,创建带参数的宏,理解符号表(全局宏与局部宏解析),宏条件运算符,在宏中进行运算

宏类似于c中的函数,传入指定参数后执行,并且宏内部可以包含data步程序和条件运算符号. 宏变量只是小小的变量....(by the way作用也很大) 1:宏的基本语法 如何创建一个简单的宏并使用? %macro prtlast; proc print data=&syslast (obs=5); title "Listing of &syslast data set"; run; %mend; %prtlast /*不要加分号,加了有可能出错*/ 宏创建过程中做了什

内联函数和宏比较

函数内联用内联取代宏代码----------------C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度).在C程序中,可以用宏代码提高执行效率.宏代码本身不是函数,但使用起来象函数.预处理器用复制宏代码的方式代替函数调用,省去了参数压栈.生成汇编语言的CALL调用.返回参数.执行return等过程,从而提高了速度. 使用宏代码最大的缺点是容易出错,预处理器在复制宏代码时常常产生意想不到的边际效应. 对于C++ 而言,使用宏代码还有另一种缺点:无法操作类的私有数据成员. 让我们看看

C语言添加宏开关

原文地址:http://blog.csdn.net/cp1300/article/details/7773239 我们在写程序的时候,总是或多或少会加入一些printf之类的语句用于输出调试信息,但是printf语句有个很不方便的地方就是当我们需要发布程序的时候要一条一条的把这些语句删除,而一旦需要再次调试的时候,这些语句又不得不一条条的加上,这给我们带来了很大的不便,浪费了我们很多的时间,也造成了调试的效率低下.所以,很多人会选择使用宏定义的方式来输出调试语句. 比如,定义一个宏开关: #de