C++ COM вне процесса маршалинга данных через прокси \ заглушка

Я пытаюсь создать внекорпусный com-сервер в каком-нибудь exe-файле и клиенте, который получит доступ к функциям через proxy\stub механизм. У меня есть файл.idl:

[
    object,
    uuid(eaa27f4f-ad6b-4a52-90f3-6028507751a1),
    dual,
    nonextensible,
    helpstring("IConfig Interface"),
    pointer_default(unique)
]
interface IInterractionInterface : IDispatch
{
    [id(1), helpstring("Testing function")] HRESULT Test([in] long param);
};


[
    uuid(6fde5037-3034-4ae1-8aa7-2ad45e5716e4),
    version(1.0),
    helpstring("Some lib")
]
library SomeLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    [
        uuid(86feabe4-a0a7-45b5-bcd4-f4f7085d6b1f),
        helpstring("Some lib")
    ]
    coclass Interraction
    {
        [default] interface IInterractionInterface;
    };
}

Я сгенерирован с помощью midl-компилятора _p.c, _i.c файлов, создал прокси \stub dll с использованием.def:

LIBRARY        proxy_stub.dll
DESCRIPTION    'generic proxy/stub DLL'
EXPORTS        DllGetClassObject      @1 PRIVATE
               DllCanUnloadNow        @2 PRIVATE
               DllRegisterServer      @4 PRIVATE
               DllUnregisterServer    @5 PRIVATE

Тогда я зарегистрировал эту DLL, используя regsrv32и в реестре win у меня есть это:

На моем сервере я создал фабрику:

CoRegisterClassObject(CLSID_InterractionInterfaceFactory, (IClassFactory*) &factory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &regID);

И это ждет клиентских звонков. В клиенте я называю свою фабрику, используя CreateInstance:

result = CoGetClassObject(CLSID_InterractionInterfaceFactory, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void**)&factory);

if (S_OK == result)
{
    IInterractionInterface* iface = NULL;

    result = factory->CreateInstance(NULL, IID_InterractionInterface, (void**)&iface);
    if (S_OK == result)
    {

    }
}

И клиент получает ноль iface и результат E_UNEXPECTED, но на фабрике это создает успешно, и я возвращаю S_OK с фабрики::CreateInstance(), Я не могу понять, механизм PS использует мои.dll или нет? Может быть, я забыл несколько шагов? Почему мой объект не может пройти через границы процесса?

Изменить: я пытался заменить клиентский код, и теперь это:

result = CoCreateInstance(CLSID_InterractionInterfaceFactory, NULL, CLSCTX_LOCAL_SERVER, IID_InterractionInterface, (void**)&iface);
iface->Test(1);

И когда я пытаюсь вызвать Test(1), он выдает ошибку, что это чисто виртуальная функция. И на фабрике в CreateInstance я получаю требование интерфейса Unkonown.

1 ответ

Если вы хотите использовать прокси / заглушку DLL, определите интерфейс вне library блок. Только вещи, определенные за пределами library идет в код, сгенерированный для прокси / заглушки DLL. Материал, определенный или на который есть ссылка, внутри library Блок переходит в сгенерированную библиотеку типов. Типичный файл IDL определяет интерфейсы вне library, а затем упоминает их внутри, в coclass блоки; таким образом, определения интерфейсов заканчиваются как прокси / заглушкой, так и TLB, для максимальной гибкости.

Ваш интерфейс совместим с автоматизацией (ну, почти; измените тип параметра с int на long). В этом случае вы можете предпочесть использовать так называемый "универсальный" маршаллинг, основанный на библиотеке типов. Просто зарегистрируйте сгенерированный MIDL файл TLB с regtlib инструмент или программно с LoadTypeLibExи у вас будет поддержка маршалинга.

Другие вопросы по тегам