在Linux下实现COM组件

好久没有写代码啦,今天翻到大学时候写的COM组件,当时那个叫崇拜COM技术啊。不过发现,工作中根本没啥用处。反正没事干,想想把COM组件在Linux环境下,实现一下。 COM组件是一种编程规范,它规定了软件编程的一般方法,虽然它由Microsoft公司制定和提出,但是它的规则也可以在Linux下使用,下面是在Linux下实现COM组件的方法。 ----参考《COM技术内幕》一书。 COM实现的技术,主要是C++的虚函数、多继承以及动态链接库(DLL)技术。 COM组件的实现: --类型定义文件type.h #ifndef TYPE_H #define TYPE_H typedef long HRESULT; typedef unsigned long ULONG; typedef struct _GUID { unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } GUID; typedef GUID IID; #define interface struct #define E_NOINTERFACE 0x80004002L #define S_OK 0 #endif --GUID定义文件guids.cpp #include "type.h" extern "C" { extern const IID IID_IX = {0x32bb8320, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; extern const IID IID_IY = {0x32bb8321, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; extern const IID IID_IZ = {0x32bb8322, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; extern const IID IID_IUnknown = {0x32bb8323, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}}; } --接口基类:IUnknown.h #ifndef IUNKNOWN_H #define IUNKNOWN_H #include "type.h" interface IUnknown { virtual HRESULT QueryInterface(const IID& iid, void** ppv)=0; virtual ULONG AddRef()=0; virtual ULONG Release()=0; }; #endif --接口定义头文件iface.h #ifndef IFACE_H #define IFACE_H #include "IUnknown.h" interface IX:IUnknown { virtual void Fx()=0; }; interface IY:IUnknown { virtual void Fy()=0; }; interface IZ:IUnknown { virtual void Fz()=0; }; extern "C" { extern const IID IID_IX; extern const IID IID_IY; extern const IID IID_IZ; } #endif --组件实现文件cmpnt1.cpp #include #include "type.h" #include "iface.h" #include "guids.cpp" using namespace std; bool operator==(const IID& guid1, const IID& guid2) { if(guid1.Data1 != guid2.Data1) return false; if(guid1.Data2 != guid2.Data2) return false; if(guid1.Data3 != guid2.Data3) return false; for(int i = 0; i < 8; i++) { if(guid1.Data4[i] != guid2.Data4[i]) return false; } return true; } void trace1(const char* msg) { cout << "Component1:/t" << msg << endl; } class CA:public IX { private: //IUnknown interface virtual HRESULT QueryInterface(const IID& iid, void** ppv); virtual ULONG AddRef(); virtual ULONG Release(); //IX interface virtual void Fx() { cout << "FX" << endl; } public: //Constructor CA():m_cRef(0){} //Destructor ~CA(){ trace1("CA Destoryed by itself!"); } private: long m_cRef; }; HRESULT CA::QueryInterface(const IID& iid, void** ppv) { if(iid == IID_IX) { trace1("Return Pointer to IX"); *ppv = static_cast (this); } else if(iid == IID_IUnknown) { trace1("Return Pointer to IUnknown"); *ppv = static_cast (this); } else { trace1("Interface is not surpport!"); *ppv = NULL; return E_NOINTERFACE; } reinterpret_cast (*ppv)->AddRef(); return S_OK; } ULONG CA::AddRef() { m_cRef++; } ULONG CA::Release() { if((--m_cRef) == 0) { delete this; return 0; } return m_cRef; } extern "C" IUnknown* CreateInstance() { IUnknown* pI = static_cast (new CA); pI->AddRef(); return pI; } 客户端的实现: --create.h #ifndef CREATE_H #define CREATE_H #include #include "IUnknown.h" #include using namespace std; struct CREATE { void* handle; IUnknown* CallCreateInstance(char *name); void closeHandle(); }; #endif --创建组件create.cpp #include "create.h" typedef IUnknown* (*CREATEFUNCPTR)(); IUnknown* CREATE::CallCreateInstance(char* name) { CREATEFUNCPTR CreateInstance; char* error; IUnknown* pUnknown; handle = dlopen(name , RTLD_LAZY); if(!handle) { cout << "Load lib " << name << " fail!" << endl; exit(1); } dlerror(); *(void**)(&CreateInstance) = dlsym(handle, "CreateInstance"); if ((error = dlerror()) != NULL) { cout << error << endl; exit(1); } pUnknown = CreateInstance(); // dlclose(handle); return pUnknown; } void CREATE::closeHandle() { dlclose(handle); } bool operator==(const IID& guid1, const IID& guid2) { if(guid1.Data1 != guid2.Data1) return false; if(guid1.Data2 != guid2.Data2) return false; if(guid1.Data3 != guid2.Data3) return false; for(int i = 0; i < 8; i++) { if(guid1.Data4[i] != guid2.Data4[i]) return false; } return true; } --客户端实现client1.cpp #include #include "iface.h" #include "create.h" #include "guids.cpp" void trace(const char* msg) { cout << "Client1:/t" << msg << endl; } int main(int argc, char** argv) { HRESULT hr; char name[40]; CREATE create; cout << "Enter the file name of a component to use[lib***.so]:"; cin >> name; cout << endl; trace("Get an IUnknown pointer."); IUnknown* pUnknown = create.CallCreateInstance(name); if(pUnknown == NULL) { trace("CallCreateInstance fail!"); exit(1); } trace("Get Interface IX."); IX* pIX = NULL; hr = pUnknown->QueryInterface(IID_IX, (void**)&pIX); if(hr >= 0) { trace("Success get the IX."); pIX->Fx(); pIX->Release(); } else { trace("Counld not get the IX interface."); } trace("Release the IUnknown interface."); pUnknown->Release(); create.closeHandle(); return 0; } --Makefile objects=cmpnt1.o client1.o create.o all : libcmpnt1 client1 libcmpnt1 : cmpnt1.o g++ -shared -W1,-soname -O3 -o libcmpnt1.so cmpnt1.o cmpnt1.o : guids.cpp iface.h IUnknown.h type.h g++ -c -fPIC cmpnt1.cpp -O3 -o cmpnt1.o client1 : client1.o create.o g++ -g -rdynamic -ldl -o client1 client1.o create.o client1.o : g++ -g -c client1.cpp create.o : g++ -g -c create.cpp .PYTHON : clean clean : rm -f ${objects} 运行时注意:需要保证当前的环境下环境变量LD_LIBRARY_PATH已经设置。 具体运行方法如下: [root@localhost cust_comp]# export LD_LIBRARY_PATH=. [root@localhost cust_comp]# ./client1 Enter the file name of a component to use[lib***.so]:libcmpnt1.so Client1: Get an IUnknown pointer. Client1: Get Interface IX. Component1: Return Pointer to IX Client1: Success get the IX. FX Client1: Release the IUnknown interface. Component1: CA Destoryed by itself!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值