COMET - an Erlang-to-COM driver

Document Sample
COMET - an Erlang-to-COM driver Powered By Docstoc
					Comet - an Erlang-to-COM Port

   Comet is a port and a gen_server module that enables
    Erlang programs to deploy COM components
   Comet is under development, an early version is part of
    OTP release 7B

   Common Object Model
   A standard for component development from Microsoft
   Windows-only (although a third-party version exist on
   Rival to CORBA on the Windows platform
   All Microsoft programs use COM
   Support for distribution, DCOM and COM+
COM Model

   Classes presents interfaces
   Interfaces are a bunch of related functions or methods
   No data are exposed, only interfaces
   Properties of objects accessible through access-functions
COM Model continued

   IDL describes classes and interfaces
   IDL compiles into a type-library that can be browsed with
    a tool
   Two ways to use a class
     – Dispatch - a special interface for interpreted languages
     – Virtual Interface - faster, for compiled languages
   Comet can use both (although dispatch is safer)
COM Memory Handling

   Reference-counting
   Language support in Visual Basic, “Java” (and C#)
   Erlang programs must (currently) explicitly free interfaces
Erlang Ports

   A way to call external code from Erlang
   Implemented as a linked in driver (DLL) or a port program
   Comet offers both
     – port driver is considerably faster
     – port program is safer, if the COM server crashes, it
       won’t bring the emulator down
   A gen_server module interfaces to the port program or
   The Comet port driver and program are multithreaded
Comet as a Port Driver

   An application calling a COM Object
     – Comet as a driver

      Erlang process
      some_application       ErlComDrv.dll


Comet as a Port Program

   An application calling a COM Object
     – Comet as a port program

      Erlang process
      some_application       ErlComDrv.exe


Calling COM from Erlang

   All calls through the gen_server module “erl_com”
   erl_com provides methods for calling
   erl_com has functions for:
     – creating objects
     – fetching interfaces
     – releasing interfaces and objects
     – retrieving type information of objects and types
     – creating threads for calling COM objects
A Simple Example

   An interface that implements some utilities
interface ISomeUtilities : IDispatch
    HRESULT DaysBetween([in] DATE date1, [in] DATE date2,
                        [out, retval] double* daysBetween);
    HRESULT ReplaceAll([in] BSTR inStr, [in] BSTR keyStr, [in] BSTR newStr,
                       [out, retval] BSTR* outStr);

   Calling it from Erlang
S= “It was a dark and stormy night...”,
I= erl_com:create_dispatch(T, “{class id for SomeUtilities}”),
S2= erl_com:invoke(I, “ReplaceAll”, [S, “stormy”, “still”]),
D= erl_com:invoke(I, “DaysBetween”, [{vt_date, {{2000, 1, 1}, {0, 0, 0}}},
                                     {vt_date, erlang:now()}])
Mapping COM Types to Erlang

   COM uses a small set of types
   Comet mapps Erlang types to COM types through the use
    of tuples
     – Basic types are converted properly: integers, floats,
        strings and booleans
     – Other types are prefixed in a tuple, e.g. {vt_date
       {1999, 12, 12}, {}}
   Constants in COM are enumerations
   Strings currently 8-bits in Comet
   Complex types as structures, are currently not supported
 Invoke (dispatch interface)

    The invoke method in the dispatch interface is used to late-
     bind to interfaces
    Comet provides the methods invoke, property_put and
Obj= erl_com:create_object(T, “{class id}”),
I= erl_com:query_interface(Obj, “{a dispatch interface id}”),
Value= erl_com:invoke(I, “Method”, [parameters]),
erl_com:property_put(I, “Property”, [parameters], Value2),
Value3= erl_com:property_get(I, “AnotherProperty”),

    Errors returned as {com_error, Code}
    Can have named parameters (not support in Comet yet)
Calling a Virtual Interface

   A virtual interface is an array of function pointers
     – Virtual Method Table used for C++ objects
   Called in Comet using assembler glue
     – Every parameter, including return value, must be
       explicitly typed
     – Address of virtual function must be specified
     – Only practical when code is generated
   Wrong parameters cause Comet to crash

[Outstr]= erl_com:com_call(I_, 36, [{vt_str, InStr}, {vt_str, out}]),
 Browser Example

    The Internet Explorer browser presents COM interfaces
    Example: creating an Internet Explorer and navigating to a
      1 opens a Comet process and a thread in it
      2 creates an object, retrieves its default interface
      3 invokes the methods “navigate” and the “visible”

 {ok, Pid}= erl_com:start_process(),
    T= erl_com:new_thread(Pid),
    Obj= erl_com:create_dispatch(T, "InternetExplorer.Application",
?CLSCTX_LOCAL_SERVER),                                                2
    erl_com:invoke(Obj, "Navigate", [""]),
    erl_com:property_put(Obj, "Visible", true),            3
 Excel Example

    Excel is also accessible through COM
    Easiest way is to start with a Visual Basic-program
      – The Excel macro recorder can generate these
    Example: adding a graph

Visual Basic:
ActiveChart.ChartType = xlPieExploded

Charts = erl_com:package_interface(E, erl_com:property_get(E, "Charts")),
erl_com:invoke(Charts, "Add"),
C= erl_com:package_interface(E, erl_com:property_get(E, "ActiveChart")),
erl_com:property_put(C, "ChartType", ?XlPieExploded),
Generating Glue Code

   Can be used for both virtual- and dispatch-interfaces
   Type libraries, compiled from COM IDL, describes COM
    classes and interfaces
   Comet reads information from Type Libraries
   Erlang modules are generated with glue code
   Each interface generates a module
   Each enum (set of constants) generates a module and a
    header-file with macros
Excel Example with Generated Code

     –   (Code is generated from the Excel type-library)

Visual Basic:
ActiveChart.ChartType = xlPieExploded
ActiveChart.SetSourceData _
     Source:=Sheets("Sheet1").Range("B2:C4"), _
ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet1"

ActiveChart= xc_Application:activeChart(E),
chart:chartType(ActiveChart, ?XlPieExploded),
R= sheets:range(xc_Application.sheets(E, “Sheet1”), “B2:C4”),
chart:setSourceData(ActiveChart, R, ?xlColumns),
chart:location(ActiveChart, ?xlLocationAsObject, "Sheet1"),

   Combining an object-oriented approach with Erlang’s
   Handling state
   Memory management
   Type conversions between Erlang and other system
   Asynchronous operations
   Performance considerations
   Robustness
Future Improvements

   Feedback needed
   Improvements considered
     – Full Unicode support
     – Calling Erlang from COM
        – Event Sinks
        – Erlang COM Servers
     – COM+ Distribution
     – Complex types
     – Other API’s on other platforms
     – Combining COM’s ref-counting with Erlang’s GC

   Comet documentation from OTP
   Don Box: Essential COM (Addison Wesley)
   Box, Brown, Ewald and Sells: Effective COM (Addison
   Oberg: Understanding & Programming COM+ (Prentice
   Jason Pritchard: COM and Corba Side by Side (Addison

Shared By: