Hi,
Introduction:
*************** ******
I am writing a mixed mode application I have a COM module and a .NET module
that communicate with each other.
The COM exposes a custom sink interface, the .NET module implement the Sink
interface ( IUnknown based ) and the COM call the methods of this interface
asynchronously.
The problem:
*************** ******
When calling the sink methods on the .NET module from the context of a
managed thread ( the main app thread ) created by the .NET framework
everything works fine BUT when calling the sink methods ( implemented by the
managed module ) from an unmanaged thread that was created by the COM module
I get E_NOINTERFACE.
Note that The managed sink implementation is associated with the COM module
through an Advice( ISink sink, ref uint uiContext ) method.
What may cause this problem? I called CoInitializeEx on all of the new
unmanaged threads…
Following is a code snap of the two modules:
Unmanaged COM:
############### ############### ############### ###
interface IMediaEvents
{
virtual HRESULT OnState(eState state, VARIANT &var) = 0;
};
Protected:
HRESULT Fire_OnState(IN eState state, IN VARIANT &var)
{
HRESULT hrRet = S_OK;
SinkVector_t::i terator itr = m_vecSink.begin ();
while(itr != m_vecSink.end() )
{
//////////////////////////////
// Returns E_NOINTERFACE!! !
if(FAILED((*itr )->OnState(stat e, var)))
hrRet = S_FALSE;
//////////////////////////////
itr++;
}
return hrRet;
}
Public:
STDMETHOD(Advis e)(IMediaEvents * pSink,
ULONG* pulCookie)
{
…
while(itr != m_vecSink.end() )
{
if(pSink == (*itr).p)
return HRESULT_FROM_WI N32(ERROR_ALREA DY_CONNECTED);
itr++;
}
m_vecSink.push_ back(spSink);
*pulCookie = (ULONG)spSink.p ;
return S_OK;
}
STDMETHOD(Unadv ise)(/*[in]*/ ULONG ulCookie)
{
…
}
Managed Sink
############### ###############
public class Form1 : System.Windows. Forms.Form
, StreamingServer Lib.IMediaEvent s
{
…
…
…
private void btnRecord_Click (object sender, System.EventArg s e)
{
if(null != m_RecordSession )
{
m_RecChan.Unadv ise(m_uiRecCook ie);
m_MediaBuffer.C loseSession(m_R ecordSession);
m_RecordSession = null;
}
m_RecChan = null;
m_RecChan = m_MediaBuffer.C reateChan(txtOu tputPath.Text, -1);
///////////////////////////////////////////////
// Connects with the COM object
m_uiRecCookie = m_RecChan.Advis e(this);
…
m_RecordSession .Start(txtSourc ePath.Text);
}
/////////////////////////////////////////////////////////////////
// Called by the COM only when executed from a managed thread
// when invoked by an unmanaged thread E_NOINTERFACE is returned
// to the unmanaged caller
public void OnState(Streami ngServerLib.eSt ate state,
object varParam)
{
…
}
…
…
};
Nadav
http://www.sophin.com