Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ATL Event Firing - pDispatch is wrong type

Status
Not open for further replies.

StevieK

Programmer
Jul 18, 2001
25
GB
Im' trying to fire events from a C++ ATL COM Object, but the code that gets generated by the "Implement Connection Points" option in VC++ doesn't work.

It generates the following code:

VOID Fire_ConnectedToTelephonyServerOrNot(LONG errorLevel, BSTR errorString, BSTR statusString)
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[3];
int nConnections = m_vec.GetSize();

for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[2] = errorLevel;
pvars[1] = errorString;
pvars[0] = statusString;
DISPPARAMS disp = { pvars, NULL, 3, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete[] pvars;
}

However, when this is run the call to pDispatch->Invoke(...) causes an &quot;Instruction at ... referenced memory at ... . The memory could not be 'read'.&quot; exception when the calling .exe is run.*

After a look at the code, my team-mate decided that the line ...

IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);

... should be changed to use a dynamic_cast instead, ....

IDispatch* pDispatch = dynimic_cast<IDispatch*>(sp.p);

... and we then found that the dynamic cast causes an exception, because pDispatch is not the correct type.

Can anyone tell me how to go about firing events from an ATL COM Object? (They should be received by Visual Basic).

Thanks in Advance,
Stephen

*=[For extra weirdness... If the calling app. is run in debug-mode (in Visual Basic), the event will fire okay, and then after Visual Basic is closed, the memory read exception dialogue appears.]
 
The code looks fine - it's the standard proxy code and it typically works with VB; dynamic_cast<> won't work I imagine since you're validating a pointer passed from VB which probably knows nothing about VC++ RTTI. In any case, the correct COM way to check you have the required interface pointer would be to use say CComQIPtr with the IID of IDispatch, i.e., you query for IDispatch:
That is, instead of:

IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);

you could write:

CComQIPtr<IDispatch,&IID_IDispatch> pDispatch = sp.p;

OTOH, it's unlikely VB is passing anything else. Also it's better not to change wizard generated code, since it will be overwritten if you regenerate the proxy. The most common cause of such errors is that your VB code has an incorrect version of your COM object. Memory reference errors at termination are often caused by releasing a reference too soon. Without more knowledge of your app it's hard to say anything more helpful. :) Hope that this helped! ;-)
 
Just in case anyone is interested... The problem was that I was using multiple threads inside the COM, and firing the events from these... from outside of the Apartment that the IUnknown interface was marshalled for. To get round this, I used a Microsoft solution...


.. Unfortunately, now the events fire without causing exceptions, but when my client app closes it hangs. This seems to be an actual known bug...


... But I don't know how to go about fixing it... Michael Lindig (on the above link) says that &quot;The problem is that the Unadvise call will fail in this state. The event handling routine needs more time .... If the event handling routine has not finished while you call [Unadvise] then [the program will hang]&quot;.

Thing is that my DLLs are all finished when the app closes anyway. Hmm.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top