G
Guest
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::iterator itr = m_vecSink.begin();
while(itr != m_vecSink.end())
{
//////////////////////////////
// Returns E_NOINTERFACE!!!
if(FAILED((*itr)->OnState(state, var)))
hrRet = S_FALSE;
//////////////////////////////
itr++;
}
return hrRet;
}
Public:
STDMETHOD(Advise)(IMediaEvents* pSink,
ULONG* pulCookie)
{
…
while(itr != m_vecSink.end())
{
if(pSink == (*itr).p)
return HRESULT_FROM_WIN32(ERROR_ALREADY_CONNECTED);
itr++;
}
m_vecSink.push_back(spSink);
*pulCookie = (ULONG)spSink.p;
return S_OK;
}
STDMETHOD(Unadvise)(/*[in]*/ ULONG ulCookie)
{
…
}
Managed Sink
##############################
public class Form1 : System.Windows.Forms.Form
, StreamingServerLib.IMediaEvents
{
…
…
…
private void btnRecord_Click(object sender, System.EventArgs e)
{
if(null != m_RecordSession)
{
m_RecChan.Unadvise(m_uiRecCookie);
m_MediaBuffer.CloseSession(m_RecordSession);
m_RecordSession = null;
}
m_RecChan = null;
m_RecChan = m_MediaBuffer.CreateChan(txtOutputPath.Text, -1);
///////////////////////////////////////////////
// Connects with the COM object
m_uiRecCookie = m_RecChan.Advise(this);
…
m_RecordSession.Start(txtSourcePath.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(StreamingServerLib.eState state,
object varParam)
{
…
}
…
…
};
Nadav
http://www.sophin.com
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::iterator itr = m_vecSink.begin();
while(itr != m_vecSink.end())
{
//////////////////////////////
// Returns E_NOINTERFACE!!!
if(FAILED((*itr)->OnState(state, var)))
hrRet = S_FALSE;
//////////////////////////////
itr++;
}
return hrRet;
}
Public:
STDMETHOD(Advise)(IMediaEvents* pSink,
ULONG* pulCookie)
{
…
while(itr != m_vecSink.end())
{
if(pSink == (*itr).p)
return HRESULT_FROM_WIN32(ERROR_ALREADY_CONNECTED);
itr++;
}
m_vecSink.push_back(spSink);
*pulCookie = (ULONG)spSink.p;
return S_OK;
}
STDMETHOD(Unadvise)(/*[in]*/ ULONG ulCookie)
{
…
}
Managed Sink
##############################
public class Form1 : System.Windows.Forms.Form
, StreamingServerLib.IMediaEvents
{
…
…
…
private void btnRecord_Click(object sender, System.EventArgs e)
{
if(null != m_RecordSession)
{
m_RecChan.Unadvise(m_uiRecCookie);
m_MediaBuffer.CloseSession(m_RecordSession);
m_RecordSession = null;
}
m_RecChan = null;
m_RecChan = m_MediaBuffer.CreateChan(txtOutputPath.Text, -1);
///////////////////////////////////////////////
// Connects with the COM object
m_uiRecCookie = m_RecChan.Advise(this);
…
m_RecordSession.Start(txtSourcePath.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(StreamingServerLib.eState state,
object varParam)
{
…
}
…
…
};
Nadav
http://www.sophin.com