C ++ COM通过代理\存根进行编程外编组数据

时间:2013-08-02 12:11:29

标签: c++ com out-of-process

我正在尝试在某个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注册表中我有这个: enter image description here

在我的服务器中,我创建了工厂:

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)
    {

    }
}

客户端收到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接口的要求。

1 个答案:

答案 0 :(得分:2)

如果要使用代理/存根DLL,请在library块之外定义接口。只有在library之外定义的内容才会进入为代理/存根DLL生成的代码中。在library块内定义或引用的Stuff进入生成的类型库。典型的IDL文件定义library之外的接口,然后在coclass块中提及它们;这样,接口定义最终会在代理/存根和TLB中结束,以获得最大的灵活性。

您的界面是自动兼容的(好吧,差不多;将参数类型从int更改为long)。在这种情况下,您可能更喜欢使用基于类型库的所谓“通用”编组。只需使用regtlib工具注册MIDL生成的TLB文件,或使用LoadTypeLibEx以编程方式注册,您就可以获得编组支持。