Ошибка "Интерфейс не зарегистрирован" на внешнем интерфейсе обратного вызова ATL
У меня есть внутрипроцессный сервер ATL, который реализует интерфейс обратного вызова следующим образом:
.idl
interface IClientEvents : IUnknown{
[] HRESULT TestEvent(void);
};
interface IATLSimpleObject : IDispatch{
[id(1)] HRESULT Advise([in] IClientEvents* clientEvents);
[id(2)] HRESULT Unadvise(void);
};
.час
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#
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();
}
Это работает нормально, но мне нужно сделать то же самое на внешнем сервере, однако при выполнении я получаю ошибку "Интерфейс не зарегистрирован" (80040105) при вызове "ATLSimple.Advise(this)".
Я часами искал похожие проблемы, но ничего не могу найти. Любая помощь будет принята с благодарностью.
1 ответ
Для того, чтобы это работало вне процесса, вам необходимо организовать интерфейсы между процессами. Скорее всего, вы захотите использовать маршаллинг автоматизации, который использует typelib, сгенерированный из вашей IDL, чтобы найти, что и как маршалировать. Проблема в том, что будет работать только для интерфейсов, которые помечены [oleautomation]
, [dual]
или оба в IDL. Смотрите этот ответ для более подробной информации.
Лучше всего пометить интерфейсы, которые вы хотите маршалировать как [oleautomation]
и добавление комментария, такого как "Marshalling magic исчезнет, если вы удалите это".