EnumInterface library
The EnumInterface assists in the creation of COM-style iterators,
that is, IEnum* interfaces which all support the following set of
methods,
interface IEnum<It> : IUnknown {
HRESULT Next
( [in] ULONG num
, [ out
, size_is(num)
, length_is(*numFetched)
] <It>** outP
, [out] ULONG *numFetched
);
HRESULT Skip ( [in] ULONG num );
HRESULT Reset ( void );
HRESULT Clone ( [out] <It>** ppv );
};
They collectively allow you to (repeatedly) iterate over a sequence
of elements (of type It here).
However, since IDL doesn't allow you to parameterise over the element
type you're iterating over, you end up having to define one IEnum
interface per type.
Not much we can do about that, but at least EnumInterface
provides you with a generic Haskell implementation of such a
family of interfaces:
mkEnumInterface :: [a]
-> Int
-> (Ptr a -> a -> IO ())
-> IO (ComVTable iid objState)
The mkEnumInterface action creates a method table containing
the above four IEnum methods. It takes the following arguments:
Here's an example of its use:
enumInts :: IO (IEnumInt ())
enumInts = do
vtbl <- mkEnumInterface [1..] HDirect.sizeofInt (HDirect.writeInt)
createComInstance "" () [mkIface iidIEnumInt vtbl] iidIEnumInt
type IEnumInt a = IUnknown (IEnumInt_ a)
dats IEnumInt_ a = IEnumInt__
iidIEnumInt :: IID (IEnumInt ())
iidIEnumInt = mkIID "{...}"