в, общем, вот так вот у меня
Код | interface IMyInterface : public virtual IUnknown { ... char __cdecl fA( void ) = 0; ... };
interface ISomeOther : public virtual IMyInterface { ... char __cdecl fB( void ) = 0; ... };
class CMyInterface : public virtual IMyInterface { public: CMyInterface() { }; virtual ~CMyInterface() { }; virtual HRESULT __stdcall QueryInterface( const IID &riid, void** ppvObject ); virtual ULONG __stdcall AddRef( void ); virtual ULONG __stdcall Release( void ); ... virtual char __cdecl fA(); };
class CSomeOther : public CMyInterface, public ISomeOther { public: CMyInterface() { }; virtual ~CMyInterface() { }; virtual HRESULT __stdcall QueryInterface( const IID &riid, void** ppvObject ); ... virtual char __cdecl fB(); };
...
HRESULT __stdcall CMyInterface::QueryInterface( const IID &riid, void** ppvObject ) { if ( riid == __uuidof(IUnknown) ) *ppvObject = (IUnknown*)this; else if ( riid == __uuidof(IMyInterface) ) *ppvObject = (IMyInterface*)this; else { *ppvObject = NULL; return E_NOINTERFACE; } ((IUnknown*)*ppvObject)->AddRef(); return S_OK; }
...
HRESULT __stdcall CSomeOther::QueryInterface( const IID &riid, void** ppvObject ) { if ( riid == __uuidof(IUnknown) ) *ppvObject = (IUnknown*)this; else if ( riid == __uuidof(IMyInterface) ) *ppvObject = (IMyInterface*)this; else if ( riid == __uuidof(ISomeOther) ) *ppvObject = (ISomeOther*)this; else { *ppvObject = NULL; return E_NOINTERFACE; } ((IUnknown*)*ppvObject)->AddRef(); return S_OK; } .... // дальше код для примера IUnknown* p = (IUnknown*)new CSomeOther(); ISomeOther* pSomeOther = NULL; p->QueryInterface(__uuidof(ISomeOther),(void**)&pSomeOther);
|
входит в метод QueryInterface обьекта CSomeOther, вылетает на строке AddRef() upd понял, кажется, в чём ошибка, но как её избежать - нет. АddRef надо проводить непосредственно к тому типу, которого есть этот объект. Если брать IUnknown, то ловлю акцесс виолейшон в c++, и, соответсвтенно, приведение полученого указателя методом IInterface(Ptr) в процедуре supports ( в дельфи ) и даёт исключение. Как с этим быть? почесав голову, добавляю. в дельфи получилось сделать IUnknown(Ptr).QueryInterface(ISomeOther,pSomeOther), Ptr получил простой экспортируемой функцией из dlll, которая возварщает мне объект типа IUnknown*, который получен с помощью dynamic_cast. с++ в ответ на QueryInterface мне передаёт dynamic_cast<ISomeOther*>(this). но при этом при вызове метода pB из pSomeOther со свежеполученного интерфейса опять валится av. интерфейс в дельфи задекларирован так же, как и в c++, с поправками:
Код | IMyInterface = interface(IUnknown) [".."] function pA() : AnsiChar; cdecl; end; ISomeOther = interface(IMyInterface) [".."] function pB() : AnsiChar; cdecl; end;
|
|