分享
 
 
 

用C模拟实现COM机制——COMSample

王朝other·作者佚名  2006-12-20
窄屏简体版  字體: |||超大  

COM似乎生来就与C++有关,虽然它一再强调COM本身与语言无关,但由于C语言本身对面相对象支持不够好,也就似乎和COM离得比较远,但也不是不能实现。本文用C模拟实现了COM机制,对于一些在如BREW平台上开发的程序员,和想更深入学习C语言的人或许有那么一点微薄的帮助。

What is COM

1.Component Object Modell(组件对象模型)

2.Reference count

3.Virtual-table(VTBL)

4.QueryInterface

实现

一 基本宏定义

//定义用于接口查询的ID

#define ID_SAMPLE_IQueryInterface 0x00000001

#define ID_SAMPLE_ISampleBase 0x00000002

//定义IBase,所有类的基类

#define IBase(iname) void (*AddRef) (iname*); void (*Release) (iname*)

//定义IQueryInterface,从IBase继承

#define IQueryInterface(iname) IBase(iname); int (*QueryInterface)(iname *, int, void **)

二 例一:基本的Addref和Release

1 接口定义

//定义ISampleBase接口

#define ISampleBase(iname) IBase(iname); void (* show)()

typedef struct SampleBase SampleBase;

//定义虚表

typedef struct ISampleBaseVtbl ISampleBaseVtbl;

struct ISampleBaseVtbl {

ISampleBase(SampleBase);

};

//SampleBase结构体,继承自IBase

struct SampleBase {

ISampleBaseVtbl * pvtbl;//虚表指针

int nref;

};

//宏定义,方便使用

#define SampleBaseAddRef(p) (*(ISampleBaseVtbl **)p)->AddRef(p)

#define SampleBaseRelease(p) (*(ISampleBaseVtbl **)p)->Release(p)

#define SampleBaseShow(p) (*(ISampleBaseVtbl **)p)->show()

2 接口实现

void SampleBase_AddRef(SampleBase * me)

{

++me->nref;

printf("SampleBase 引用计数加一(引用计数为:%d)\n", me->nref);

}

void SampleBase_Release(SampleBase * me)

{

--me->nref;

printf("SampleBase 引用计数减一(引用计数为:%d)\n", me->nref);

//如果引用计数归零,则释放内存

if (0 == me->nref) {

printf("引用计数为零,释放内存\n");

free(me);

}

}

void SampleBase_Show()

{

printf("this is SampleBase show\n");

}

void SampleBase_Init(SampleBase ** me)

{

//为实例和虚函数表分配空间

(*me) = (SampleBase * )malloc(sizeof(SampleBase) + sizeof(ISampleBaseVtbl));

//虚函数表指针指向实际虚函数表位置,两种方法都可

(*me)->pvtbl = (ISampleBaseVtbl * )(((char *)(*me)) + sizeof(SampleBase));

//(*me)->pvtbl = (ISampleBaseVtbl * )((*me) + 1);

(*me)->pvtbl->AddRef = SampleBase_AddRef;

(*me)->pvtbl->Release = SampleBase_Release;

(*me)->pvtbl->show = SampleBase_Show;

(*me)->nref = 1;

printf("创建SampleBase 引用计数为1\n");

}

3 使用

void TestSampleBase()

{

SampleBase * p;

printf("--------TestSampleBase---------\n\n");

SampleBase_Init(&p);

SampleBaseAddRef(p);

SampleBaseRelease(p);

SampleBaseShow(p);

SampleBaseRelease(p);

printf("\n================================\n");

}

三 例二:继承和多态的实现

1 接口定义

#define ISampleInherit(iname) ISampleBase(iname); void (* show2)()

typedef struct SampleInherit SampleInherit;

//定义虚表

typedef struct ISampleInheritVtbl ISampleInheritVtbl;

struct ISampleInheritVtbl {

ISampleInherit(SampleInherit);

};

//SampleInherit结构体,继承自ISampleBase

struct SampleInherit {

ISampleInheritVtbl * pvtbl;

int nref;

};

//宏定义,方便使用

#define SampleInheritAddRef(p) (*(ISampleInheritVtbl **)p)->AddRef(p)

#define SampleInheritRelease(p) (*(ISampleInheritVtbl **)p)->Release(p)

#define SampleInheritShow(p) (*(ISampleInheritVtbl **)p)->show()

#define SampleInheritShow2(p) (*(ISampleInheritVtbl **)p)->show2()

2 接口实现

void SampleInherit_AddRef(SampleInherit * me)

{

++me->nref;

printf("SampleInherit 引用计数加一(引用计数为:%d)\n", me->nref);

}

void SampleInherit_Release(SampleInherit * me)

{

--me->nref;

printf("SampleInherit 引用计数减一(引用计数为:%d)\n", me->nref);

if (0 >= me->nref) {

printf("引用计数为零,释放内存\n");

free(me);

}

}

void SampleInherit_Show()

{

printf("this is SampleInherit show\n");

}

void SampleInherit_Show2()

{

printf("this is SampleInherit show2\n");

}

void SampleInherit_Init(SampleInherit ** me)

{

(*me) = (SampleInherit * )malloc(sizeof(SampleInherit) + sizeof(ISampleInheritVtbl));

//(*me)->pvtbl = (ISampleInheritVtbl * )(((char *)(*me)) + sizeof(SampleInherit));

(*me)->pvtbl = (ISampleInheritVtbl * )((*me) + 1);

(*me)->pvtbl->AddRef = SampleInherit_AddRef;

(*me)->pvtbl->Release = SampleInherit_Release;

(*me)->pvtbl->show = SampleInherit_Show;

(*me)->pvtbl->show2 = SampleInherit_Show2;

(*me)->nref = 1;

printf("创建SampleInherit 引用计数为1\n");

}

3 使用

void TestSampleInherit()

{

SampleInherit * p;

printf("-------TestSampleInherit--------\n\n");

SampleInherit_Init(&p);

SampleInheritShow(p);

SampleInheritShow2(p);

SampleBaseShow(p);//以派生类实例调用基类接口,多态关键

SampleInheritRelease(p);

printf("\n================================\n");

}

四 例三:多重继承和接口查询的实现

1 接口定义

#define ISampleInherit3(iname) IQueryInterface(iname); void (* show3)()

typedef struct SampleInherit3 SampleInherit3;

//定义虚表

typedef struct ISampleInherit3Vtbl ISampleInherit3Vtbl;

struct ISampleInherit3Vtbl {

ISampleInherit3(SampleInherit3);

};

typedef struct {

ISampleBaseVtbl * pvt;

SampleInherit3 * pme;

}IISampleBase;

//SampleInherit3结构体,同时继承自IQueryInterface和SampleBase

struct SampleInherit3 {

ISampleInherit3Vtbl * pvtbl;

int nref;

IISampleBase a;

ISampleBaseVtbl vta;

};

//宏定义,方便使用

#define SampleInherit3AddRef(p) (*(ISampleInherit3Vtbl **)p)->AddRef(p)

#define SampleInherit3Release(p) (*(ISampleInherit3Vtbl **)p)->Release(p)

#define SampleInherit3QueryInterface(p,ID,ppo) (*(ISampleInherit3Vtbl **)p)->QueryInterface(p,ID,ppo)

#define SampleInherit3Show3(p) (*(ISampleInherit3Vtbl **)p)->show3()

2 接口实现

void SampleInherit3_AddRef(SampleInherit3 * me)

{

++me->nref;

printf("SampleInherit3 引用计数加一(引用计数为:%d)\n", me->nref);

}

void SampleInherit3_Release(SampleInherit3 * me)

{

--me->nref;

printf("SampleInherit3 引用计数减一(引用计数为:%d)\n", me->nref);

if (0 >= me->nref) {

printf("引用计数为零,释放内存\n");

free(me);

}

}

int SampleInherit3_QueryInterface(SampleInherit3 * me, int iid, void ** ppo)

{

if (ID_SAMPLE_IQueryInterface == iid) {

*ppo = me;

printf("(该实例支持QueryInterface接口)\n");

SampleInherit3_AddRef(me);

return 1;

} else if (ID_SAMPLE_ISampleBase == iid) {

*ppo = &me->a;

printf("(该实例支持SampleBase接口)\n");

SampleInherit3_AddRef(me);

return 1;

} else {

*ppo = 0;

return 0;

}

}

void SB_AddRef(SampleBase * me)

{

SampleInherit3AddRef(((IISampleBase*)me)->pme);

}

void SB_Release(SampleBase * me)

{

SampleInherit3Release(((IISampleBase*)me)->pme);

}

void SampleInherit3_Show()

{

printf("this is SampleInherit3 show\n");

}

void SampleInherit3_Show3()

{

printf("this is SampleInherit3 show3\n");

}

void SampleInherit3_Init(SampleInherit3 ** me)

{

(*me) = (SampleInherit3 * )malloc(sizeof(SampleInherit3) + sizeof(ISampleInherit3Vtbl));

//(*me)->pvtbl = (ISampleInheritVtbl * )(((char *)(*me)) + sizeof(SampleInherit));

(*me)->pvtbl = (ISampleInherit3Vtbl * )((*me) + 1);

(*me)->pvtbl->AddRef = SampleInherit3_AddRef;

(*me)->pvtbl->Release = SampleInherit3_Release;

(*me)->pvtbl->QueryInterface = SampleInherit3_QueryInterface;

(*me)->pvtbl->show3 = SampleInherit3_Show3;

(*me)->nref = 1;

(*me)->vta.AddRef = SB_AddRef;

(*me)->vta.Release = SB_Release;

(*me)->vta.show = SampleInherit3_Show;

(*me)->a.pvt = &(*me)->vta;

(*me)->a.pme = (*me);

printf("创建SampleInherit3 引用计数为1\n");

}

3 使用

void TestSampleInherit3()

{

SampleInherit3 * p;

SampleBase * a;

printf("-------TestSampleInherit3--------\n\n");

SampleInherit3_Init(&p);

SampleInherit3Show3(p);

if (SampleInherit3QueryInterface(p,ID_SAMPLE_ISampleBase,&a)) {

SampleBaseShow(a);

SampleBaseRelease(a);

}

SampleInherit3Release(p);

printf("\n=================================\n");

}

小结

本文通过三个简单的例子,模拟了C++的继承和多态,以及COM机制。具体的实现(如BREW平台)要复杂的多,定义了大量的宏,但基本原理都一样。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有