代码之家  ›  专栏  ›  技术社区  ›  Armentage

从非托管代码获取COM对象

  •  3
  • Armentage  · 技术社区  · 16 年前

    我有一个库,它导出一个非托管C例程,该例程返回指向基于COM IUnknown的对象的指针。DLL未注册,也不是服务器。我想使用C中的COM类型。

    我已经为COM类型编写了C接口。调用loadLibrary()和getProcAddress()的C等价物是什么?如何调用getProcAddress()的结果,然后调用它来加载COM接口指针?

    下面是C++的片段,它说明了我在做什么:

    // Assume I have previously declared IMyType
    HANDLE mylib = ::LoadLibrary("myfakecom.dll");
    IUnknown* (*GetterFunc) getter;
    getter = (GetterFunc)::GetProcAddress(mylib, "GetFactory");
    IUnknown *unk = getter();
    IMyType *mytype = unk->QueryInterface(IID_MYTYPE);
    

    我的直觉说“用C++ + CLI做它”,虽然我不确定我将如何为任何泛型类型做这件事,我如何强制将原始的未知指针强制应用到管理器指针类型中,我将使用管理界面上的[GUID]属性声明。

    1 回复  |  直到 16 年前
        1
  •  1
  •   John Knoeller    16 年前

    您只需要使用interop来描述 GetFactory 函数,类似于这样

    [DllImport("myfakecom.dll")]
    [return: MarshalAs(UnmanagedType.IUnknown)]
    static extern object GetFactory();
    

    然后在托管代码中拥有对象。强制转换等价于QueryInterface

    void Foo(Object unk)
    {
        IMyType mytype = (IMyType)unk;
    } 
    

    您需要将C++接口定义复制为C接口定义,可能使用[MARSARLAS ]属性。但既然你已经这样做了,剩下的应该是容易的。

    我建议你把你的工厂原型从

    IUnknown * GetFactory();
    

    HRESULT GetFactory([out] IUnknown ** ppunk);
    

    COM ITerop代码似乎有一个很强的假设,即所有COM方法都返回hresult,如果您使用那里的流,那么使封送工作变得更简单。

    推荐文章