Я пытаюсь создать out-of-proc com-сервер в некотором exe-файле и клиенте, который будет обращаться к функциям через механизм proxy\stub
. У меня есть IDL-файл:C++ COM out-of-proc marshalling data через proxy stub
[
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 файлы, созданные прокси \ DLL-заглушки с помощью .def:
LIBRARY proxy_stub.dll
DESCRIPTION 'generic proxy/stub DLL'
EXPORTS DllGetClassObject @1 PRIVATE
DllCanUnloadNow @2 PRIVATE
DllRegisterServer @4 PRIVATE
DllUnregisterServer @5 PRIVATE
Тогда я зарегистрирован это дллы с помощью regsrv32
, и в выигрыше реестре у меня есть это:
в моем сервере я создал завод:
CoRegisterClassObject(CLSID_InterractionInterfaceFactory, (IClassFactory*) &factory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, ®ID);
И он ждет звонков клиентов. В клиенте я зову свою фабрику, используя 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 или нет? Может, я забыл несколько шагов? Почему мой объект не может проходить через границы процесса?
Edit: Я пытался заменить код клиента и теперь это:
result = CoCreateInstance(CLSID_InterractionInterfaceFactory, NULL, CLSCTX_LOCAL_SERVER, IID_InterractionInterface, (void**)&iface);
iface->Test(1);
И когда я пытаюсь вызвать Test (1) он выдает ошибку, что это является чистой виртуальной функцией. И на фабрике в CreateInstance я получаю требование интерфейса Unkonown.
Использование прокси-сервера требует записи раздела реестра в 'HCKR \ Interfaces', значение ProxyStubClsId32 должно быть установлено в CLSID для прокси-сервера. Не ясно, было ли это сделано правильно. E_UNEXPECTED, однако, не такая ошибка, которую вы ожидаете, когда у вас возникнут проблемы с регистрацией, вместо этого вы получите E_NOINTERFACE. Попробуйте использовать ProcMon SysInternals, вы можете получить более четкое представление о том, что происходит не так. Может быть, проблема с загрузкой DLL. –
Этот путь на снимке экрана не указан HKEY_CLASSES_TOOR \ Wow6432Node \ CLSID \ {GUID}. Это не правильно? – fryme
Это правильно, только не единственный. Вам также нужны * дополнительные * ключи, по одному в «HKCR \ Interfaces» для каждого интерфейса, реализованного сервером. Вот как COM выясняет, какой сервер необходимо использовать, когда его просят маршалировать интерфейс. Вы можете легко это увидеть в ProcMon, рекомендуется. –