最近研究安卓源码 发现了很多宏的特殊用法 记录下来以便日后巩固复习。
1、特殊符号 #
带有#的参数会被量化成字符数组,也就是在替换的时候给其两端加上" "。
例如:#define STR(x) #x
STR(a)将被替换成 "a"
2、特殊符号 ##
“##”是一种分隔连接方式,它的作用是将宏参数替换后,然后再将##两边的参数连接进行强制连接。
例如:
在普通的宏定义中,预处理器一般把空格解释成分段标志,对于每一段和前面比较,相同的就被替换。但是这样做的结果是,被替换段之间存在一些空格。如果我们不希望出现这些空格,就可以通过添加一些##来替代空格。
1 #define TYPE1(type,name) type name_##type##_type
2 #define TYPE2(type,name) type name##_##type##_type
TYPE1(int, c); 转换为:int name_int_type ; (因为##号将后面分为 name_ 、type 、 _type三组,替换后强制连接)
TYPE2(int, d);转换为: int d_int_type ; (因为##号将后面分为 name、_、type 、_type四组,替换后强制连接)
这个例子好好研究一下。
3、define的多行定义
define可以替代多行的代码,在每一个换行的时候加上一个"\"
#define MAX(X,Y) do { \
语句1; \
语句2; \
/* 注释的写法 */ \
} while(0) /* (no trailing ; ) */ \
4附上安卓的部分源码如下
IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");
下面是这个宏的定义
#defineIMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
android::sp<I##INTERFACE>I##INTERFACE::asInterface( \
constandroid::sp<android::IBinder>& obj) \
{ \
android::sp<I##INTERFACE>intr; \
if (obj != NULL) { \
intr =static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = newBp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE(){ } \
很麻烦吧?尤其是宏看着头疼。赶紧兑现下吧。
const
android::String16IServiceManager::descriptor(“android.os.IServiceManager”);
constandroid::String16& IServiceManager::getInterfaceDescriptor() const
{ return IServiceManager::descriptor;//返回上面那个android.os.IServiceManager
} android::sp<IServiceManager> IServiceManager::asInterface(
constandroid::sp<android::IBinder>& obj)
{
android::sp<IServiceManager>intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
IServiceManager::IServiceManager () {}
IServiceManager::~ IServiceManager() { }
哇塞,asInterface是这么搞的啊,赶紧分析下吧,还是不知道interface_cast怎么把BpBinder*转成了IServiceManager
我们刚才解析过的interface_cast<IServiceManager>(new BpBinder(0)),
原来就是调用asInterface(new BpBinder(0))
android::sp<IServiceManager>IServiceManager::asInterface(
constandroid::sp<android::IBinder>& obj)
{
android::sp<IServiceManager>intr;
if (obj != NULL) {
....
intr = new BpServiceManager(obj);
//神呐,终于看到和IServiceManager相关的东西了,看来
//实际返回的是BpServiceManager(new BpBinder(0));
}
}
return intr;
}