|
Suschnost' tehnologii SOM Authors: Boks D. Published year: Pages: 30-31/103 |
C++ IUnknown , ÷ C++ (runtime layer) . IUnknown , . C++, C++ , , ÷ , ÷ .
Visual Basic Java, ÷ C++, QueryInterface , AddRef Release . IUnknown ø. Java QueryInterface :
public void TryToSnoreAndIgnore(Object obj) {
IPug pug;
try {
pug = (IPug)obj;
// VM calls QueryInterface
// VM вызывает QueryInterface
pug.Snore();
} catch (Throwable ex) {
// ignore method or QI failures
// игнорируем сбой метода или QI
}
ICat cat;
try {
cat = (ICat)obj;
// VM calls QueryInterface
// VM вызывает QueryInterface
cat.IgnoreMaster();
} catch (Throwable ex) {
// ignore method or QI failures
// игнорируется сбой метода или QI
}
}
Visual Basic . , , ø (VM) Visual Basic ÷ QueryInterface :
Sub TryToSnoreAndIgnore(obj as Object) On Error Resume Next ' ignore errors ' игнорируем ошибки Dim pug as IPug Set pug = obj ' VM calls QueryInterface ' VM вызывает QueryInterface If Not (pug is Nothing) Then pug.Snore End if Dim cat as ICat Set cat = obj ' VM calls QueryInterface ' VM вызывает QueryInterface If Not (cat is Nothing) Then cat.IgnoreMaster End if End Sub
ø, Java, Visual Basic, QueryInterface ÷. ø ÷ ÷ AddRef Release , .
, C++, , ÷ . ( raw ) IUnknown . :
÷ ÷ . -, ÷ ÷ , ø, . Visual C++ 5.0, , ÷ ( MSC, ATL, Direct-to-COM), ÷ , . 1995 1996 " C++ Report " , ÷ 1 . , , -, . ÷ ø, ÷ , . , SmartInterface , ø (template) : C++ IID . IUnknown :
#include "smartif.h"
void TryToSnoreAndIgnore(/* [in] */ IUnknown *pUnk)
{
// copy constructor calls QueryInterface
// конструктор копирования вызывает QueryInterface
SmartInterface<IPug, &IID_IPug> pPug = pUnk;
if (pPug)
// typecast operator returns null-ness
// оператор приведения типа возвращает нуль
pPug->Snore();
// operator-> returns safe raw ptr
// оператор -> возвращает прямой указатель
// copy constructor calls QueryInterface
// конструктор копирования вызывает QueryInterface
SmartInterface<ICat, &IID_ICat> pCat = pUnk;
if (pCat)
// typecast operator returns null-ness
// оператор приведения типа возвращает нуль
pCat->IgnoreMaster();
// operator-> returns safe raw ptr
// оператор -> возвращает прямой указатель
// destructors release held pointers on leaving scope
// деструкторы освобождают удерживаемые указатели при
// выходе из области действия
}
÷ , ÷ , ; ÷ ø , , . ø , ÷; , . , ÷ -> . , Release - , ÷ ÷ Release ø .
1 http:/www.develop.com/dbox/cxx/InterfacePtr.htm http://www.develop.com/dbox/cxx/SmartPtr.htm.
÷ QueryInterface , , ÷ , C++. , , . ÷ ø ø ø . , ÷ , IID - , - . , QueryInterface , , , ø if , ÷ static_cast ( static_cast , ÷ vptr ).
× QueryInterface , ÷ , ÷ . , IID , vptr ø . , ÷ ÷ , . ÷ inttable.h , :
// inttable.h (book-specific header file)
// inttable.h (заголовочный файл, специфический для этой книги)
// typedef for extensibility function
// typedef для функции расширяемости
typedef HRESULT (*INTERFACE_FINDER)
(void *pThis, DWORD dwData, REFIID riid, void **ppv);
// pseudo-function to indicate entry is just offset
// псевдофункция для индикации того, что запись просто
// является смещением
#define ENTRY_IS_OFFSET INTERFACE_FINDER(-1)
// basic table layout
// представление базовой таблицы
typedef struct INTERFACE_ENTRY {
const IID * pIID;
// the IID to match
// соответствующий IID
INTERFACE_FINDER pfnFinder;
// функция finder
DWORD dwData;
// offset/aux data
// данные по offset/aux
} INTERFACE_ENTRY;
÷ :
// Inttable.h (book-specific header file)
// Inttable.h (заголовочный файл, специфический для данной книги)
#define BASE_OFFSET(ClassName, BaseName) \
(DWORD(static_cast<BaseName*>(reinterpret_cast\
<ClassName*>(0x10000000))) - 0х10000000)
#define BEGIN_INTERFACE_TABLE(ClassName) \
typedef ClassName _ITCls;\
const INTERFACE_ENTRY *GetInterfaceTable(void) {\
static const INTERFACE_ENTRY table [] = {\
#define IMPLEMENTS_INTERFACE(Itf) \
{&IID_##Itf,ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls,Itf)},
#define IMPLEMENTS_INTERFACE_AS(req, Itf) \
{&IID_##req,ENTRY_IS_OFFSET, BASE_OFFSET(_ITCls, Itf)},
#define END_INTERFACE_TABLE() \
{ 0, 0, 0 } }; return table; }
, ÷ , - , QueryInterface . Inttable.h :
// inttable.cpp (book-specific source file)
// inttable.h (заголовочный файл, специфический для данной книги)
HRESULT InterfaceTableQueryInterface(void *pThis,
const INTERFACE_ENTRY *pTable,
REFIID riid, void **ppv)
{
if (InlineIsEqualGUID(riid, IID_IUnknown)) {
// first entry must be an offset
// первый элемент должен быть смещением
*ppv = (char*)pThis + pTable->dwData;
((Unknown*) (*ppv))->AddRef () ; // A2
return S_OK;
}
else {
HRESULT hr = E_NOINTERFACE;
while (pTable->pfnFinder) { // null fn ptr == EOT
if (!pTable->pIID InlineIsEqualGUID(riid,*pTable->pIID)) {
if (pTable->pfnFinder == ENTRY_IS_OFFSET) {
*ppv = (char*)pThis + pTable->dwData;
((IUnknown*)(*ppv))->AddRef(); // A2
hr = S_OK;
break;
}
else {
hr = pTable->pfnFinder(pThis, pTable->dwData, riid, ppv);
if (hr == S_OK) break;
}
}
pTable++;
}
if (hr != S_OK) *ppv = 0;
return hr;
}
}
÷ ø , InterfaceTableQueryInterface , ø IID , , . ø ø IsEqualGUID , ø , 20-30 ø , . InterfaceTableQueryInterface , .
÷ C++, ÷ , -. ÷ impunk.h QueryInterface , AddRef Release , ÷ :
// impunk.h (book-specific header file)
// impunk.h (заголовочный файл, специфический для данной книги)
// AUTO_LONG is just a long that constructs to zero
// AUTO_LONG - это просто long, с конструктором,
// устанавливающим значение в О
struct AUTO_LONG {
LONG value;
AUTO_LONG (void) : value (0)
};
#define IMPLEMENT_UNKNOWN(ClassName) \
AUTO_LONG m_cRef;\
STDMETHODIMP QueryInterface(REFIID riid, void **ppv){\
return InterfaceTableQueryInterface(this,\
GetInterfaceTable(), riid, ppv);\
}\
STDMETHODIMP_(ULONG) AddRef(void) { \
return InterlockedIncrement(&m_cRef.value); \
}\
STDMETHODIMP_(ULONG) Release(void) {\
ULONG res = InterlockedDecrement(&m_cRef.value) ;\
if (res == 0) \
delete this;\
return res;\
}\
÷ , ÷ .
PugCat , ÷ ø , ø QueryInterface , AddRef Release :
class PugCat : public IPug, public ICat {
protected:
virtual ~PugCat(void);
public:
PugCat(void);
// IUnknown methods
// методы IUnknown
IMPLEMENT_UNKNOWN (PugCat)
BEGIN_INTERFACE_TABLE(PugCat)
IMPLEMENTS_INTERFACE(IPug)
IMPLEMENTS_INTERFACE(IDog)
IMPLEMENTS_INTERFACE_AS(IAnimal,IDog)
IMPLEMENTS_INTERFACE(ICat)
END_INTERFACE_TABLE()
// IAnimal methods
// методы IAnimal
STDMETHODIMP Eat(void);
// IDog methods
// методы IDog
STDMETHODIMP Bark(void);
// IPug methods
// методы IPug
STDMETHODIMP Snore(void);
// ICat methods
// методы ICat
STDMETHODIMP IgnoreMaster(void);
};
, IUnknown . , ÷ , , .
|
Suschnost' tehnologii SOM Authors: Boks D. Published year: Pages: 30-31/103 |