SML# - OLESMLSharpMiniGuideOfCOM Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

// COM in 3 minutes.

Microsoft COM (= Component Object Model) is object-based interoperability infrastructure.
In other words, COM provides object-based shared library and inter process communication.
OLE is upper layer of COM.

Compared to shared library, COM is characterized as follows.

!!Shared library

* Library name is a path in a file system.
* Library exports functions.

!!COM

!!!Component name is UUID.

A component is identified by UUID, which is 128bit almost global unique ID.
For example, Microsoft Internet Explorer has its UUID:
{0002DF01-0000-0000-C000-000000000046}

COM infrastructure manages mapping between UUID and the location
of implementation code of the service identified by the UUID.
In Windows, static information about this mapping is stored in registry.
For the above UUID, the registry has an entry at
HKEY_CLASSES_ROOT\CLSID\{0002DF01-0000-0000-C000-000000000046}
By using C:/WINDOWS/regedit.exe, you can see there that the UUID is mapped
to an executable file:
"C:\Program Files\Internet Explorer\iexplore.exe"

!!!Component exports object.

From client, COM object is seen as a pair of instance data and an array of
function pointers.
Its layout resembles those of object which Microsoft C++ compiler generates.
So, a COM object is seen as an usual object in C++ program if you use MS
compiler.

The following is an approximate code in pseudo C to access Internet Explorer.

typedef struct tagIInternetExplorerVtbl
{
   void (*setVisible)(IInternetExplorer* this, bool visible);
   bool (*getVisible)(IInternetExplorer* this);
   void (*navigate)(IInternetExplorer* this, string url);
   void (*quit)(IInternetExplorer* this);
} IInternetExplorerVtbl;

typedef struct tagIInternetExplorer
{
   IInternetExplorerVtbl* vtbl;
} IInternetExplorer;

UUID IEUUID = {0002DF01-0000-0000-C000-000000000046};

IInternetExplorer* ie = (IInternetExplorer*)CoCreateInstance(IEUUID);
  
ie->vtbl->setVisible(ie, true);
ie->vtbl->navigate(ie, "http://www.pllab.riec.tohoku.ac.jp/smlsharp/");
ie->vtbl->quit(ie);

!Topics in OLE/SML#.

// Oveview of OLE/SML#

''OLE/SML#'' is a support tool to enable SML code to access Microsoft COM/OLE objects.

''OLE/SML#'' depends on SML# features including FFI, LMLML, Finalizer and FLOB.

!Components.

:OLE2SML.exe: Given a type library, this command generates SML# source code to access COM objects which are described in the type library.
:OLE.sml: Base library to access Microsoft COM infrastructure.

!Usage.

OLE2SML.exe generates SML code from user specified type library.

$ OLE.exe [options] TYPELIB_FILENAME
$ OLE.exe [options] ProgID

Type library can be specified by
* file path of the type library, or
* ProgID of a Coclass of which type information is described in the type library.

Options:

:-c CLASSNAME: generates wrapper codes for specified coclasses or dispatch interfaces only. You can use this option more than once. If no ''-c'' option is specified, wrappers for all coclasses and dispatch interfaces are generated.
:-o FILENAME: writes wrapper code into the specified file name. If no ''-o'' option is specified, file name is ''TYPELIBNAME.sml'' .
:-h: shows usage.

!Example.

For example, let's write a SML# code to operate Internet Explorer (=IE).

First, use OLE2SML.exe to generate a wrapper code for IE.

OLE2SML takes a ProgID as its command line parameter.
ProgID of IE is "InternetExplorer.Application".

$ OLE2SML.exe InternetExplorer.Application

Instead of ProgID, you can specify the file path of the type library.

$ OLE2SML.exe "C:\\WINDOWS\\System32\\shdocvw.dll"

The type library ''C:\WINDOWS\System32\shdocvw.dll'' defines COM objects
implemented in Internet Explorer.

By default, ''OLE2SML.exe'' generates code for every coclass and interfaces
described in the specified type library.
If you use only some of them, you can specify them with ''-c'' option to reduce the size of generated code.

$ OLE2SML.exe -c InternetExplorer InternetExplorer.Application
$ OLE2SML.exe -c InternetExplorer "C:\\WINDOWS\\System32\\shdocvw.dll"

The generated code contains code for InternetExplorer coclass only.

The following session creates an IE instance, navigates to Home page.

# use "OLE.sml";
     :
# OLE.initialize [OLE.COINIT_MULTITHREADED];
val it = () : unit

Loads and initializes the OLE library.

# use "./SHDocVw.sml";
signature SHDocVw =
     :
end
structure SHDocVw : SHDocVw

Loads the generated wrapper code for IE.
The wrapper code defines a structure with the name of the type library.

# val IE = SHDocVw.newInternetExplorer ();
val IE =
    {
      :
    }
    : SHDocVw.InternetExplorer

Creates an instance of IE.
'''new'''''coclass'' is the constructor function of ''coclass''.

# #getVisible IE ();
val it = false : bool
# #setVisible IE true;
val it = () : unit

Accesses the '''visible''' property of IE.

# #GoHome IE ();
val it = () : unit

Invokes the '''GoHome''' method of IE.

# #release IE ();
val it = 0wx0 : Word32.word

COM manages the life cycle of objects by reference count.
OLE/SML# manages reference count of each COM object internally, depending on
GC of SML#, so you does not have to call '''addRef''' and '''release'''
explicitly.
In this example, however, the reference to an IE object is bound at global.
Because a global binding will not become garbage in GC of SML#,
you have to call '''release''' after use, so that global binding is released.

# OLE.uninitialize ();
val it = () : unit

Clean-up OLE library.

!!Other examples.
*[[Internet Explorer|http://www.pllab.riec.tohoku.ac.jp/smlsharp/tools/OLE/sample/SHDocVwSample.sml]]
*[[Excel|http://www.pllab.riec.tohoku.ac.jp/smlsharp/tools/OLE/sample/ExcelSample.sml]]
*[[Windows Scripting|http://www.pllab.riec.tohoku.ac.jp/smlsharp/tools/OLE/sample/ScriptingSample.sml]]
*[[Late binding|http://www.pllab.riec.tohoku.ac.jp/smlsharp/tools/OLE/sample/DotNetSample.sml]]

!Topics in OLE/SML#.

*[[OLESMLSharpOverview]]
*[[OLESMLSharpMapping]]
*[[API|http://www.pllab.riec.tohoku.ac.jp/smlsharp/tools/OLE/doc/api/]]
*[[OLESMLSharpMiniGuideOfCOM]]
*[[OLESMLSharpImplementationOverview]]