My goals is to generate bridging code that allows to call a COM interface in Java. I do use successfully JNA, insofar as I get an handle to the interface and can successfully work with most of the functionality of the interface.
I have a question regarding several interfaces that are similar to the following pattern (I think the snippet is self-contained):
[
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);
};
If this interface is imported into Visual Studio and used in a C# project, then C# detects that the above implements the interface IEnumerator and allows to iterate over the elements. Moreover C# even knows the iterated type, being an 'IVariable'.
Q1: How does C# or its COM-interface importer draw the conclusion that 'IVariables' above implements 'IEnumerator' and the enumerated elements are of type 'IVariable'?
Obviously the line
[id(0xfffffffc), propget, helpstring("property _NewEnum")]
must do the trick. But while I found the same construct in other IDLs, I cannot find any explanation on this in Google. Maybe related is that I get no information whatsoever on the types of properties from the IDL, see
[id(0x00000002), propget, helpstring("property Parent")]
in the above IDL. There is neither a type 'Parent' nor a type 'IParent'. Thus:
Q2: Is it possible to derive the type of a COM property from its IDL and if yes how?
Finally, when importing the above types into C# the above IDL is actually not used. Instead the importer expects the executable for the OLE-enabled application, to read its typelib (similar to the Microsoft oleview.exe tool). This leads me to my last question:
Q3: Is there an API that can be used to query the OLE interface of an executable and does this offer addditional metadata?
Thanks for insights.
1) because the dispid is a well-known one: DISPID_NEWENUM (-4) that designates an enumerator. The item's type (IVariable
) can be deduced from the Item
(the indexer) member which uses 0 (DISPID_VALUE).
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) yes, if the property type is specified in the idl (duh), but here you're looking at a pure late-binding interface (IDispatch
only), which is fully dynamic, so no, in this case.
3) .IDL
is not used because the .TLB
format is equivalent, and programmable through ITypeLib et al. Only the MIDL compiler uses IDL. At runtime, there's not much more than the TLB available in the general case. COM in its simplest form basically only needs IUnknown
and that's it.
User contributions licensed under CC BY-SA 3.0