【发布时间】:2019-07-15 16:44:46
【问题描述】:
我的目标是生成允许在 Java 中调用 COM 接口的桥接代码。我确实成功地使用了 JNA,只要我获得了接口的句柄并且可以成功地使用接口的大部分功能。
我有一个关于类似于以下模式的几个接口的问题(我认为sn-p是自包含的):
[
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”。
Q1:C# 或其 COM 接口导入器如何得出上述“IVariables”实现“IEnumerator”且枚举元素为“IVariable”类型的结论?
很明显
[id(0xfffffffc), propget, helpstring("property _NewEnum")]
必须做到这一点。但是,虽然我在其他 IDL 中发现了相同的结构,但我在 Google 中找不到任何解释。也许相关的是我没有从 IDL 获得任何关于属性类型的信息,请参阅
[id(0x00000002), propget, helpstring("property Parent")]
在上面的 IDL 中。既没有“Parent”类型,也没有“IParent”类型。因此:
Q2:是否可以从 IDL 中获取 COM 属性的类型,如果可以,如何获取?
最后,在将上述类型导入 C# 时,实际上并没有使用上述 IDL。相反,导入器希望启用 OLE 的应用程序的可执行文件读取其类型库(类似于 Microsoft oleview.exe 工具)。这引出了我的最后一个问题:
Q3:是否有 API 可用于查询可执行文件的 OLE 接口,是否提供额外的元数据?
感谢您的见解。
【问题讨论】:
-
不是 C# 执行此操作,而是类型库导入器。 Tlbimp.exe 是独立工具,它生成的互操作库具有为它提供类似 C# 接口的管道。 Dispid -4 等效于 GetEnumerator(),Dispid 0 是它派生元素类型的索引器。 tlbimp 的托管版本已在 Codeplex 上发布,我认为它是 here now。它有点牛。