问题
I have an ATL in-process server that implements a callback interface like so:
.idl
interface IClientEvents : IUnknown{
[] HRESULT TestEvent(void);
};
interface IATLSimpleObject : IDispatch{
[id(1)] HRESULT Advise([in] IClientEvents* clientEvents);
[id(2)] HRESULT Unadvise(void);
};
.h
private:
IClientEvents* m_ClientEvents;
public:
STDMETHOD(Advise)(IClientEvents* clientEvents);
STDMETHOD(Unadvise)(void);
.cpp
STDMETHODIMP CATLSimpleObject::Advise(IClientEvents* clientEvents)
{
m_ClientEvents = clientEvents;
m_ClientEvents->AddRef();
return S_OK;
}
STDMETHODIMP CATLSimpleObject::Unadvise(void)
{
m_ClientEvents->Release();
m_ClientEvents = NULL;
return S_OK;
}
C# client
public partial class Form1 : Form, ATLProject1Lib.IClientEvents
{
private ATLProject1Lib.ATLSimpleObject ATLSimple = new ATLProject1Lib.ATLSimpleObject();
private void Form1_Shown(object sender, EventArgs e)
{
ATLSimple.Advise(this);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
ATLSimple.Unadvise();
}
It works fine, but I need to do exactly the same in an out-of-process server, however, on execution I get an 'Interface not Registered' (80040105) error when calling 'ATLSimple.Advise(this)'.
I've spent hours searching for similar problems, but can't find anything. Any help would be greatly appreciated.
回答1:
In order for this to work out-of-proc you need the interfaces to be marshalled between processes. Most likely you will want to rely on Automation marshalling which uses a typelib generated from your IDL to find what and how to marshall. The problem is that will only work for interfaces that are marked [oleautomation], [dual] or both in the IDL. See this answer for more details.
You best bet is marking the interfaces you want marshalled as [oleautomation] and adding a comment like "Marshalling magic goes away if you remove this".
来源:https://stackoverflow.com/questions/17875073/interface-not-registered-error-on-atl-out-of-process-callback-interface