/HCOM

Haskell COM client library

Primary LanguageHaskellOtherNOASSERTION

HCOM
====

HCOM is a COM interop layer for Haskell. You can use it to instantiate
COM objects and call methods on them.

Strengths:
 - Small, (relatively) simple code
 - Efficient static, vtbl-based dispatch - doesn't need OLE automation

Weaknesses:
 - Doesn't provide a mechanism to write your own COM servers
 - Requires manual coding of stubs from IDL or a typelib
 - Doesn't play nicely with the COM threading model

HCOM is not a particularly complete piece of work - the weaknesses are
not so much intrinsic as the result of laziness. We have the
functionality we need, and cannot justify extra investment of time and
effort at this point! That includes the writing of thorough, detailed
documentation.

We hope that it will be of some use to others, though!

The rest of this document compares us to the competition (com-1.2.3),
gives an overview of the source, briefly discusses how to use the
library, and highlights the rough corners/areas for improvement.

Alternatives and previous work:
-------------------------------

Before starting on HCOM, we considered the com-1.2.3 package, which
appears to be the packaged version of H/Direct [1,2]. From our point of
view, the problems we had were:
 - Some types we needed were not supported
 - It seemed mostly focused on OLE automation (the IDispatch
   dynamically-dispatchd scripting interface, rather than native ABI
   bindings).
 - It was not clear what the state of maintenance was
 - The code seemed quite complex, with a large code base

So, we built our own package to our own requirements (see 'strengths')
above.

The paper on Visual Haskell [3] covers COM bindings in section 5. It
discusses many of the experiences we've had, especially with thread
safety (see 'weaknesses'). It also discusses a similar experience to
ours with com-1.2.3.

Files:
------

Stack.hs:        Functions to help construct a call stack to be used
                 with the COM call.

COMCall.hs:      Given an object, vtbl entry and stack, invoke a COM
                 function.

RawFunctions.hs: Win32 types and symbol imports.

Tags.hs:         Data type tags used by Variants and Safearrays
BSTR.hs:         BSTR marshalling
GUID.hs:         GUID marshalling
HResult.hs:      A wrapper for the HResult type
SafeArray.hs:    SAFEARRAY marshalling
Variant.hs:      A wrapper for the VARIANT type
COMPtr.hs:       A wrapper for COM objects

Functions.hs:    Haskell-exposed version of the Win32 COM API functions.

ErrorInfo.hs:    Handling of the ErrorInfo extended error information.
COMException.hs: A type representing a COM error.

Generated files:
----------------

Currently the 'generated' files are hand-rolled, but they still live in
the 'Gen' subdirectory.

To create a method binding, you need to know the method's position in
the vtbl, and the size and shape of the arguments. Get the binding
wrong and your program is likely to crash.

This requires quite a detailed understanding of the COM ABI, but given
that you can get a fairly nice and neat binding. Yes, autogenerated
bindings from typelibs or IDL would be nice!

Example code:
-------------

The code in the 'Testing' directory shows you how to create and call bindings.

That's about it, I'm afraid.

There's an underlying assumption that you know a fair amount about COM
if you want to use this package. I recommend Don Box's 'Essential
COM'.

FIXME:
------

Variants still need to support byref.

An improved testing framework?

Fix up the source
 * Remaining FIXMEs
 * Haddock comments

Add support for actually auto-generating the wrappers, based on TLBs,
etc.

Helpful documentation.

Need to check for null pointers more carefully in returned values!

When we do explicit memory management, make it exception-safe? (cf
RAII in C++)

Add handling for methods with >2 arguments in x64 (up to ~20 arguments supported in x86).

References:
-----------

[1]

@INPROCEEDINGS{Leijen:hdirect,
author      = {Sigbj\"orn Finne and Daan Leijen and Erik Meijer and Peyton Jones, Simon},
title       = {{H}/{D}irect: {A} {B}inary {F}oreign {L}anguage {I}nterface to {H}askell},
booktitle   = {Proceedings of the International Conference on Functional Programming ({ICFP'98})},
address     = {{B}altimore, {USA}},
year        = {1998},
note        = {Also appeared in {ACM SIGPLAN} {N}otices 34, 1, (Jan. 1999)}
}

[2]

@ARTICLE{Finne:1999:CHH:317765.317790,
 author = {Finne, Sigbjorn and Leijen, Daan and Meijer, Erik and Peyton Jones, Simon},
 title = {Calling hell from heaven and heaven from hell},
 journal = {SIGPLAN Not.},
 issue_date = {Sept. 1999},
 volume = {34},
 number = {9},
 month = sep,
 year = {1999},
 issn = {0362-1340},
 pages = {114--125},
 numpages = {12},
 url = {http://doi.acm.org/10.1145/317765.317790},
 doi = {10.1145/317765.317790},
 acmid = {317790},
 publisher = {ACM},
 address = {New York, NY, USA},
}

[3]

@INPROCEEDINGS{vshaskell05,
   author = {Krasimir Angelov and Simon Marlow},
   title = {Visual Haskell: A full-featured Haskell development environment},
   booktitle = {Haskell '05: Proceedings of the 2005 ACM SIGPLAN workshop on Haskell},
   year = {2005},
   month = {September},
   url = {http://www.haskell.org/~simonmar/papers/vshaskell.pdf},
   doi = {http://doi.acm.org/10.1145/1088348.1088350},
   isbn = {1-59593-071-X},
   pages = {5--16},
   location = {Tallinn, Estonia},
   publisher = {ACM Press}
}