1

我正在尝试在一些 exe 文件和客户端中创建进程外 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 创建代理\存根 dll:

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

    }
}

并且客户端收到 null iface 并且结果是E_UNEXPECTED,但是在工厂中它成功创建并且我从 Factory:: 返回 S_OK CreateInstance()。我不明白 PS 机制是否使用我的 .dll?也许我忘记了一些步骤?为什么我的对象不能通过进程边界?

编辑: 我试图替换客户端代码,现在是:

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

当我试图调用 Test(1) 时,它会抛出一个错误,这是纯虚函数。在 CreateInstance 的工厂中,我收到了 Unkonown 接口的要求。

4

1 回答 1

2

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

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

于 2013-08-03T13:21:04.190 回答