如何从 COM idl 派生所有提供的接口类型?
How to derive all offered interface types from an COM idl?
我的目标是生成允许在 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# 甚至知道迭代类型,即 'IVariable'.
问题 1:C# 或其 COM 接口导入器如何得出上述 'IVariables' 实现 'IEnumerator' 且枚举元素为 'IVariable' 类型的结论?
显然是行
[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 接口并且它是否提供额外的元数据?
感谢您的见解。
1) 因为 dispid 是众所周知的:DISPID_NEWENUM (-4) 指定枚举器。项目的类型 (IVariable
) 可以从使用 0 (DISPID_VALUE).
的 Item
(索引器)成员推导出来
DISPID_NEWENUM -4
This MUST designate the DISPID associated with a
_NewEnum method that MUST have the following signature.
HRESULT _NewEnum([out,retval] IEnumVARIANT** ppenum);
or
HRESULT _NewEnum([out,retval] IUnknown** ppenum);
2) 是的,如果在 idl 中指定了 属性 类型(废话),但这里您看到的是纯后期绑定接口(仅 IDispatch
),它是完全动态,所以不,在这种情况下。
3) .IDL
未被使用,因为 .TLB
格式是等效的,并且可以通过 ITypeLib 等进行编程。只有 MIDL 编译器使用 IDL。在运行时,一般情况下可用的 TLB 不多。最简单形式的 COM 基本上只需要 IUnknown
,仅此而已。
我的目标是生成允许在 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# 甚至知道迭代类型,即 'IVariable'.
问题 1:C# 或其 COM 接口导入器如何得出上述 'IVariables' 实现 'IEnumerator' 且枚举元素为 'IVariable' 类型的结论?
显然是行
[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 接口并且它是否提供额外的元数据?
感谢您的见解。
1) 因为 dispid 是众所周知的:DISPID_NEWENUM (-4) 指定枚举器。项目的类型 (IVariable
) 可以从使用 0 (DISPID_VALUE).
Item
(索引器)成员推导出来
DISPID_NEWENUM -4
This MUST designate the DISPID associated with a _NewEnum method that MUST have the following signature.
HRESULT _NewEnum([out,retval] IEnumVARIANT** ppenum);
or
HRESULT _NewEnum([out,retval] IUnknown** ppenum);
2) 是的,如果在 idl 中指定了 属性 类型(废话),但这里您看到的是纯后期绑定接口(仅 IDispatch
),它是完全动态,所以不,在这种情况下。
3) .IDL
未被使用,因为 .TLB
格式是等效的,并且可以通过 ITypeLib 等进行编程。只有 MIDL 编译器使用 IDL。在运行时,一般情况下可用的 TLB 不多。最简单形式的 COM 基本上只需要 IUnknown
,仅此而已。