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} }