Здравствуйте.
Есть необходимость обрабатывать некоторые события от ADO. Реализовывать это надо, насколько я понимаю, с использованием того, что MSDN называет Connectable Objects. Согласно этого написал sink-объект (текс приведен ниже), установил соединение (текст тоже ниже), вроде все окей, но когда должно возникнуть событие, компилятор сообщает об ошибке: Access violation.
В чем может быть причина?
Установка соединения
IConnectionPoint *pCPAdoRS;
CAdoSink Sink;
DWORD dwAdoCookie;
//00000266-0000-0010-8000-00AA006D2EA4
static const GUID IID_RecordsetEvents =
{0x00000266,0x0000,0x0010,{0x80,0x0,0x0,0xaa,0x0,0x6d,0x2e,0xa4}};
HRESULT hr;
IConnectionPointContainer *pCPCtrAdoRS=NULL;
hr = adoRS.m_lpDispatch->QueryInterface(IID_IConnectionPointContainer,(void **)&pCPCtrAdoRS);
hr = pCPCtrAdoRS->FindConnectionPoint(IID_RecordsetEvents, &pCPAdoRS);
hr = pCPAdoRS->Advise(&Sink, &dwAdoCookie);
Реализация sink-объекта
class CAdoSink : public IDispatch
{
public:
ULONG refCount;
CAdoSink::CAdoSink() {
refCount = 1;
}
CAdoSink::~CAdoSink() {
}
// IUnknown methods.
virtual HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObject)
{
static const GUID IID_RecordsetEvents =
{0x00000403,0x0000,0x0010,{0x80,0x0,0x0,0xaa,0x0,0x6d,0x2e,0xa4}};
if(IsEqualGUID(riid, IID_IDispatch) || IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_RecordsetEvents))
{
this->AddRef();
*ppvObject = this;
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
virtual ULONG _stdcall AddRef(void) {
return ++refCount;
}
virtual ULONG _stdcall Release(void) {
if(--refCount <= 0) {
//Delete this;
return 0;
}
return refCount;
}
// IDispatch methods.
virtual HRESULT _stdcall GetTypeInfoCount(UINT *pctinfo) {
if(pctinfo) *pctinfo = 0;
return E_NOTIMPL;
}
virtual HRESULT _stdcall GetTypeInfo(
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) {
return E_NOTIMPL;
}
virtual HRESULT _stdcall GetIDsOfNames(
REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
DISPID *rgDispId) {
return E_NOTIMPL;
}
virtual HRESULT _stdcall Invoke(
DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
// сами обработчики здесь не приведены, т.к. до сюда делов вообще не доходит
return S_OK;
}
};
Здравствуйте, Merl, Вы писали:
[]
Если все написано так как есть, то твой синк создается на стеке и при выходе из обласи видимости покидает этот бренный мир. Соответственно, когда сервер хочет дернуть метод, он получает AV. Вообще очень редко я видел, когда кокласс нужно было создавать на стеке. Обычно его создают в куче, а за удаление отвечает мезанизм подсчета ссылок.
Как быстрое решение проблемы, рекомендую просто создать объект динамически. А вообще, конечно, в коде много неточностей.
используй заголовок adoint.h
используй либу Adoid.lib
используй atl для реализации синка
Здравствуйте, Alexey Shirshov
Спасибо за ответ, однако хотелось бы получить еще некоторые пояснения. Т.к. на VC я пересел сравнительно недавно, то я невполне свободно чувствую себя с такими словами, как "стек" или "куча"
Синк у меня объявлен в секции protected класса диалогового окна (приложение dialog-based), поэтому как он мог "выйти из поля зрения" мне не понятно.
protected
//....
CAdoSink Sink
//...
Если у вас есть какие-нибудь полезные ссылки или примеры, которые вы могли бы послать мне, то я был бы вам весьма признателен
Merl
Здравствуйте, Merl, Вы писали:
[]
M>Если у вас есть какие-нибудь полезные ссылки или примеры, которые вы могли бы послать мне, то я был бы вам весьма признателен
Э...
Как бы это сказать. Я бы рад помочь, но объяснение основ языка С++ заняло бы слишком много времени и сил для меня.