Linux系統並沒有對應的註冊表和IUnknow介面,所以需要自己編寫。
型別定義 type.h
/*
$file: type.h
$date: 2020年8月13日
$author: hehl
$describe: 型別定義
$other:
*/
#ifndef __TYPE_H__
#define __TYPE_H__
typedef long HRESULT; // 32位元機爲四位元組,64位元機爲八位元組,和指針的型別長度一致
typedef unsigned long ULONG;
typedef struct _GUID
{
unsigned long Data1; // 32位元 0x0000-0x0000
unsigned short Data2; // 16位元 0x0000
unsigned short Data3; // 16位元 0x0000
unsigned char Data4[8]; // 64位元 0x0000-0x0000-0x0000-0x0000
}GUID; // guid 128位元的全域性唯一識別符號(Globally Unique Identifier)
typedef GUID IID;
#define interface struct // 定義介面爲結構體
#define E_NOINTERFACE 0x80004002L // 錯誤碼,先不管他
#define S_OK 0
#endif
介面基礎類別 iunknown.h
/*
$file: iunknown.h
$date: 2020年8月13日
$author: hehl
$describe: 介面基礎類別
$other:
*/
#ifndef __IUNKNOWN_H__
#define __IUNKNOWN_H__
#include "type.h"
interface IUnknown // interface相當於struct,c語言風格
{
virtual HRESULT QueryInterface(const IID& iid, void** ppv) = 0; // 請求介面指針,相當於查詢一個方法
virtual ULONG AddRef() = 0; // 增加參照計數
virtual ULONG Release() = 0; // 減少參照計數
}; // windows提供的IUnknown類的三個介面,Linux下需要自己實現,windows這裏爲類
#endif
/*
$file: interface.h
$date: 2020年8月13日
$author: hehl
$describe: 介面類 + GUID
$other:
*/
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
#include "iunknown.h"
interface IX : IUnknown // 這個總感覺怪怪的,先不管這種寫法了,按照c++的寫法應該是繼承把?
{
virtual void Fx() = 0; // 純虛擬函式,由派生類實現具體方法
};
interface IY : IUnknown
{
virtual void Fy() = 0; // 純虛擬函式,由派生類實現具體方法
};
interface IZ : IUnknown
{
virtual void Fz() = 0; // 純虛擬函式,由派生類實現具體方法
};
// 8 4 4 12
// 9F153BC9-E06F-7B23-F4FC-A96B64ABA9D3
extern "C"
{
const IID IID_IX = { 0x9F153BC9, 0xE06F , 0x7B23 , \
{0xF4, 0xFC, 0xA9, 0x6B, 0x64, 0xAB, 0xA9, 0xD3} };
const IID IID_IY = { 0x9F153BC9, 0xE06F , 0x7B23 , \
{0xF4, 0xFC, 0xA9, 0x6B, 0x64, 0xAB, 0xA9, 0xD4} };
const IID IID_IZ = { 0x9F153BC9, 0xE06F , 0x7B23 , \
{0xF4, 0xFC, 0xA9, 0x6B, 0x64, 0xAB, 0xA9, 0xD5} };
const IID IID_IUnknown = { 0x9F153BC9, 0xE06F , 0x7B23 , \
{0xF4, 0xFC, 0xA9, 0x6B, 0x64, 0xAB, 0xA9, 0xD6} };
}
#endif
/*
$file: component.cpp
$date: 2020年8月13日
$author: hehl
$describe: 元件實現
$other:
*/
#include <iostream>
#include "type.h"
#include "interface.h"
using namespace std;
bool operator==(const IID& guid1, const IID& guid2)
{
if (guid1.Data1 != guid2.Data1 || guid1.Data2 != guid2.Data2 || \
guid1.Data3 != guid2.Data3)
{
return false;
}
for (int i = 0; i < 8; i++)
{
if (guid1.Data4[i] != guid2.Data4[i])
{
return false;
}
}
return true;
}
// 額... = =、 類以後還是定義再標頭檔案裏面好點~~先不管了
class CA : public IX
{
private:
// IUnknown的介面
virtual HRESULT QueryInterface(const IID& iid, void** ppv);
virtual ULONG AddRef();
virtual ULONG Release();
// IX的介面
virtual void Fx();
public:
CA();
~CA();
private:
long m_cRef;
};
CA::CA()
{
cout << "CA::CA()\n";
}
CA::~CA()
{
cout << "CA::~CA()\n";
}
HRESULT CA::QueryInterface(const IID& iid, void** ppv)
{
if (iid == IID_IX)
{
cout << "CA::QueryInterface() to IX\n";
*ppv = static_cast<IX*>(this); // 等價於 *ppv = (IX*)this;
}
else if (iid == IID_IUnknown)
{
cout << "CA::QueryInterface() to IUnknown\n";
*ppv = static_cast<IUnknown*>(this);
}
else
{
cout << "CA::QueryInterface() Interface is not support\n";
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
}
ULONG CA::AddRef()
{
m_cRef++;
cout << "CA::AddRef() m_cRef:" + m_cRef << endl;
}
ULONG CA::Release()
{
if (0 == (--m_cRef))
{
delete this;
return 0;
}
return m_cRef;
}
void CA::Fx()
{
cout << "CA::Fx() called\n";
}
// 由動態庫指向此函數
extern "C" IUnknown * CreateInstance()
{
IUnknown* pI = static_cast<IX*>(new CA);
pI->AddRef();
return pI;
}
/*
$file: client.cpp
$date: 2020年8月13日
$author: hehl
$describe: 元件實現
$other:
*/
#include <iostream>
#include "interface.h"
#include "create.h"
int main(int argc, char** argv)
{
HRESULT hr;
char name[40] = { 0 };
CREATE create;
cout << "Enter the file name of a component to use[lib***.so]:";
cin >> name;
cout << "Get an IUnknown pointer." << endl;
IUnknown* pUnknown = create.CallCreateInstance(name);
if (pUnknown == NULL)
{
cout << "CallCreateInstance fail!\n";
exit(1);
}
cout << "Get Interface IX.\n";
IX* pIX = NULL;
hr = pUnknown->QueryInterface(IID_IX, (void**)&pIX);
if (hr < 0)
{
cout << "Counld not get the IX interface.\n";
}
else
{
cout << "Success get the IX interface.\n";
pIX->Fx();
pIX->Release();
}
cout << "Release the IUnknown interface.\n";
pUnknown->Release();
create.closeHandle();
return 0;
}
objects=component.o client.o create.o
all : libcmpnt client
libcmpnt:component.o
g++ -shared -Wl,-soname -O3 -o libcmpnt.so component.o
cmpnt.o : interface.h iunknown.h type.h
g++ -c -fPIC component.cpp -O3 -o component.o
client : client.o create.o
g++ -g -rdynamic -Wl,--no-as-needed -ldl -o client client.o create.o
client.o :
g++ -g -c client.cpp
create.o :
g++ -g -c create.cpp
.PYTHON : clean
clean :
rm -f ${objects}
編譯、執行