我正在尝试在某个exe文件和客户端中创建out-of-proc com服务器,它将通过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文件生成的,使用.def创建了proxy \ stub dll:
LIBRARY proxy_stub.dll
DESCRIPTION 'generic proxy/stub DLL'
EXPORTS DllGetClassObject @1 PRIVATE
DllCanUnloadNow @2 PRIVATE
DllRegisterServer @4 PRIVATE
DllUnregisterServer @5 PRIVATE
然后我使用regsrv32
注册了这个dll,在win注册表中我有这个:
在我的服务器中,我创建了工厂:
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)
{
}
}
客户端收到null iface,结果为E_UNEXPECTED
,但在工厂中它成功创建,我从Factory :: CreateInstance()
返回S_OK。
我无法理解PS机制是否使用我的.dll?也许我忘记了一些步骤?为什么我的对象无法通过进程边界?
编辑: 我试图替换客户端代码,现在它是:
result = CoCreateInstance(CLSID_InterractionInterfaceFactory, NULL, CLSCTX_LOCAL_SERVER, IID_InterractionInterface, (void**)&iface);
iface->Test(1);
当我试图调用Test(1)时,它会抛出一个错误,这是纯粹的虚函数。在CreateInstance的工厂中,我收到了Unkonown接口的要求。
答案 0 :(得分:2)
如果要使用代理/存根DLL,请在library
块之外定义接口。只有在library
之外定义的内容才会进入为代理/存根DLL生成的代码中。在library
块内定义或引用的Stuff进入生成的类型库。典型的IDL文件定义library
之外的接口,然后在coclass
块中提及它们;这样,接口定义最终会在代理/存根和TLB中结束,以获得最大的灵活性。
您的界面是自动兼容的(好吧,差不多;将参数类型从int更改为long)。在这种情况下,您可能更喜欢使用基于类型库的所谓“通用”编组。只需使用regtlib
工具注册MIDL生成的TLB文件,或使用LoadTypeLibEx
以编程方式注册,您就可以获得编组支持。