代码之家  ›  专栏  ›  技术社区  ›  Michael B

如何从COM IDL派生所有提供的接口类型?

  •  0
  • Michael B  · 技术社区  · 6 年前

    我的目标是生成桥接代码,允许在Java中调用COM接口。我确实成功地使用了jna,只要我获得了接口的句柄,并且能够成功地使用接口的大部分功能。

    我有一个关于几个类似于以下模式的接口的问题(我认为代码片段是自包含的):

    [
      odl,
      uuid(4D27AA78-B622-42E7-A237-3DA76B14A23D),
      helpstring("IVariables Interface"),
      dual,
      oleautomation
    ]
    interface IVariables : IDispatch {
        [id(0x00000001), propget, helpstring("property Application")]
        HRESULT Application([out, retval] IDispatch** pVal);
        [id(0x00000002), propget, helpstring("property Parent")]
        HRESULT Parent([out, retval] IDispatch** pVal);
        [id(0x00000003), propget, helpstring("property Count")]
        HRESULT Count([out, retval] long* pnCount);
        [id(00000000), propget, helpstring("property Item")]
        HRESULT Item(
                        [in] VARIANT index, 
                        [out, retval] IVariable** pVal);
        [id(0xfffffffc), propget, helpstring("property _NewEnum")]
        HRESULT _NewEnum([out, retval] IUnknown** ppEnum);
        [id(0x00000004), helpstring("method Add")]
        HRESULT Add(
                        [in] BSTR Name, 
                        [in, optional] VARIANT Value, 
                        [out, retval] IVariable** pVal);
        [id(0x00000005), helpstring("method Remove")]
        HRESULT Remove([in] VARIANT index);
    };
    

    如果这个接口被导入到visual studio并在c项目中使用,那么c会检测到上面的实现了这个接口 IEnumerator 并允许在元素上迭代。此外,c甚至知道迭代类型,是一个“ivvariable”。

    问题1:C或其COM接口导入程序如何得出结论,上面的“ivvariable”实现了“IEnumerator”,并且枚举的元素属于“ivvariable”类型?

    很明显这条线

    [id(0xfffffffc), propget, helpstring("property _NewEnum")]
    

    一定要玩这个把戏。但是,虽然我在其他idl中找到了相同的构造,但在google中找不到任何解释。可能与此相关的是,我没有从idl获得任何关于属性类型的信息,请参见

        [id(0x00000002), propget, helpstring("property Parent")]
    

    在上面的IDL中。既没有类型“parent”,也没有类型“iparent”。因此:

    问题2:是否可以从其idl派生com属性的类型,如果可以,如何派生?

    最后,当将上述类型导入到c中时,实际上不使用上述idl。相反,导入程序希望启用OLE的应用程序的可执行文件读取其类型库(类似于Microsoft OleView.exe工具)。这就引出了我的最后一个问题:

    问题3:是否有一个API可以用来查询可执行文件的OLE接口,这是否提供附加元数据?

    谢谢你的洞察力。

    0 回复  |  直到 6 年前
        1
  •  3
  •   Simon Mourier    6 年前

    1)因为dispid是一个众所周知的dispid: DISPID_NEWENUM (-4)指定枚举器的。项目的类型( IVariable )可以从 Item (索引器)使用0(dispid_值)的成员。

    显示新枚举-4

    这必须指定与 _必须具有以下签名的NewEnum方法。

    hresult\u newenum([out,retval]ienumvariant**ppenum);

    hresult_newenum([out,retval]iunknown**ppenum);

    2)是的,如果属性类型是在idl(duh)中指定的,但是这里您看到的是纯后期绑定接口( IDispatch 只有),这是完全动态的,所以不,在这种情况下。

    3) .IDL 不使用,因为 .TLB 格式是等效的,可通过 ITypeLib 等。只有MIDL编译器使用IDL。在运行时,没有比一般情况下可用的tlb多得多的了。com最简单的形式基本上只需要 IUnknown 就这样。