Scripting COM Components in Haskell
Total Page:16
File Type:pdf, Size:1020Kb
Scripting COM comp onents in Haskell Simon Peyton Jones simonpjdcsglaacuk Erik Meijer erikcsruunl University of Glasgow University of Utrecht Daan Leijen leijenwinsuvanl University of Amsterdam Abstract system higher order functions lazy evaluation and convenient syntax In particular we describ e an The expressiveness of higherorder typed languages interface b etween Haskell and Microsofts Comp onent such as Haskell or ML makes them an attractive Ob ject Mo del COM that makes it easy to script medium in which to write software comp onents Hith COM comp onents from a Haskell program We make erto however their use has b een limited by the all two main contributions ornothing problem it is hard to write just part of an application in these languages We describ e a graceful and stronglytyped inte Comp onentbased programming using a binary stan gration of COM into Haskell dard such as Microsofts Comp onent Ob ject Mo del If the exercise is to b e more than just Gosh we COM oers a solution to this dilemma by sp ecify can script COM in Haskell as well as in Visual ing a languageindep endent interface b etween comp o Basic then it is imp ortant to demonstrate some nents This pap er rep orts ab out our exp erience with added value from using a higherorder typed lan exploiting this opp ortunity in the purelyfunctional guage We oer such a demonstration in the form language Haskell We describ e a design for integrat of an extended case study ing COM comp onents into Haskell programs and we demonstrate why someone might want to script their COM comp onents in this way We are also excited by the dual p ossibility that of writing COM comp onents in Haskell but that is b e This paper appears in the Proceedings of the Fifth In yond the scop e of this pap er ternational Conference on Software Reuse Victoria British Columbia June Background This version includes an Appendix that is omitted from Until recently it has b een much easier for a client pro the published paper gram to use software comp onents libraries classes abstract data types written in the same language Introduction One of the attractive features of the current vogue for The sp ecication of the interface b etween the comp onentbased programming is its language inde comp onent and its clients is usually given in a p endence Instead of having to write an entire ap languagesp ecic way for example as C header plication in a single language it b ecomes p ossible to les or C class descriptions write each software comp onent in the most suitable The calling convention b etween client and com language available This p ossibility presents new op p onent is often languagesp ecic or p erhaps even p ortunities to comp onent implementors unsp ecied b ecause b oth client and comp onent In this pap er we prop ose the purelyfunctional lan are assumed to b e compiled with the same com guage Haskell as an attractive language for com piler p onent scripting that is for constructing new comp o nents by gluing together other standard comp onents Programmers can assume a rather intimate cou Haskell supp orts a number of features that make this pling b etween the address spaces of client and b oth secure and expressive a rich p olymorphic type comp onent for example the client might pass a How COM works p ointer into the middle of an array to b e side eected by the comp onent Although there are many very fat b o oks ab out COM eg the core technology is quite simple a no COM encapsulates a software comp onent in a way table achievement This section briey introduces the that contrasts with each of these three asp ects key ideas We concentrate exclusively on how COM works rather on why it works that way the COM The interface b etween client and comp onent is literature deals with the latter topic in detail sp ecied in IDL COMs Interface Denition Lan guage For each particular language to ols are Here is how a client written in C might create and provided to convert IDL into the corresp onding invoke a COM ob ject sp ecication in that language section Create the object COM sp ecies the clientcomponent interface at errcode CoCreateInstance clsid a binary level indep endently of any particular ifaceid language or compiler section ifaceptr Parameters are exp ected to b e marshalled from if not SUCCEEDEDerrcode the clients address space to the comp onents ad error recovery dress space and vice versa Sometimes the two share an address space in which case marshalling need do no copying but all COMcalls provide Invoke a method enough information to do such marshalling ifaceptr ifaceptr x y z Interfacing b etween two languages often carries The pro cedure CoCreateInstance is b est thought of p erformance overheads b ecause of diering data as a system call In real life it takes more parame representation and memoryallo cation p olicies ters than those given ab ove but they are unimp ortant When the alternative is a nativelanguage inter here Calling CoCreateInstance creates an instance face b etween client and comp onent these extra of an ob ject whose class identier or CLSID is passed overheads can seem rather unattractive in clsid The class identier is a bit globally However anyone using COM has already bitten unique identier or GUID Here globally unique the bullet they have declared themselves willing means that the GUID is a name for the class that will to accept a hit in programming convenience and not ever b e reused for any other purp ose anywhere p erhaps a hit in p erformance for marshalling in on the planet A standard utility allows an unlimited exchange for the advantages that COM brings supply of fresh GUIDs to b e generated lo cally based on the machines IP address and the date and time The ab ove p oints are not COMs only advantages The co de for the class is found indirectly via the sys For example one of the primary motivations for using tem registry which is held in a xed place in the COM concerns version control and upgrade paths for le system This double indirection of CLSIDs and software comp onents which we have not mentioned registry makes the client co de indep endent of the at all However these additional prop erties are well sp ecic lo cation of the co de for the class Next describ ed elsewhere and do not con CoCreateInstance loads the class co de into the cur cern us further in this pap er except in so far as they rent pro cess unless it has already b een loaded al serve as motivators for p eople to write and use COM ternatively one can ask COM to create a new pro cess comp onents either lo cal or remote to run the class co de Finally Also COM is not alone in having these prop erties COM asks the class co de more precisely the class Numerous research pro jects had similar goals in par factory to create an instance of the class which it ticular CORBA In fact much of the rest of this returns to the caller In fact what is returned is an pap er would apply to CORBA as well as COM Un interface pointer which we discuss next like COM though CORBA is not a binary standard to use CORBA for Haskell would required adding a Interfaces and metho d invocation language binding for Haskell to some manufacturers ORB COM is much friendlier to nonmainstream lan A COM ob ject supp orts one or more interfaces each guages of which has its own globallyunique interface iden that p oints to the structures just describ ed the client b e happy "Vtbl pointer" "Virtual function table" will (not shared) (shared by all instances) p ointers provide the sole way in which one Interface Interface QueryInterface interact with a COM ob ject This restriction pointer can it p ossible to implement location transparency AddRef makes a ma jor COM warcry whereby an ob jects client in Release with the ob ject in the same way regardless of Object teracts or not the ob ject is in the same address space state other whether even on the same machine as the client All that methods or is necessary is to build a proxy interface p ointer that does p oint into the clients address space but whose metho ds are stub pro cedures that marshal the data across the b order to and from the remote ob ject Figure Interface p ointers Getting other interfaces A single COM ob ject can supp ort more than one inter face But as we have seen b efore CoCreateInstance tier or I ID That is why CoCreateInstance takes returns only one interface p ointer So how do we a second parameter ifaceid the I ID of the de get the others Answer every interface supp orts the sired interface CoCreateInstance returns the inter QueryInterface metho d which maps an I ID to an face pointer of this interface in ifaceptr There is interface p ointer for the requested I ID or fails if the no such thing as an ob ject p ointer or ob ject iden ob ject do es not supp ort the requested interface So tier there are only interface p ointers from any interface p ointer ifaceptr on an ob ject we can get to any other interface p ointer ifaceptr The I ID of an interface uniquely identies the com which that ob ject implements for example plete signature of that interface that is what metho ds ifaceptr ifaceptr iid ifaceptr the interface has including what order they app ear in their calling convention what arguments they Why Because QueryInterface is at oset take and what results they return If we want to in every interface change the signature of an interface we must give the new interface a dierent I ID from the old one That The COM sp ecication requires that QueryInterface way when a client asks for an interface with a particu b ehaves consistently