SML# - OLESMLSharpMapping Diff

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

// mapping COM and SML#

!IDispatch and Variant.

OLE/SML# interoperates with COM objects through [[IDispatch|http://msdn.microsoft.com/en-us/library/ms221608.aspx]] interface.

Methods exposed by COM objects are accessed via [[IDispatch::Invoke|http://msdn.microsoft.com/en-us/library/ms221479.aspx]].

IDispatch::Invoke takes and returns OLE [[Variant|http://msdn.microsoft.com/en-us/library/ms221627.aspx]].
Variant is a tagged union of various data types.

!data type mapping.

Data types which can be stored in Variant are enumerated in
[[VARENUM|http://msdn.microsoft.com/en-us/library/ms221170.aspx]].
Data types indicated by VARENUM are mapped to SML# datatype as follows.

||! VARENUM ||! SML# data type
|| VT_EMPTY || ''unsupported''
|| VT_NULL || ''unsupported''
|| VT_I2 || Int32.int
|| VT_I4 || Int32.int
|| VT_R4 || Real32.real
|| VT_R8 || Real64.real
|| VT_CY || ''unsupported''
|| VT_DATE || ''unsupported''
|| VT_BSTR || OLE.string
|| VT_DISPATCH || OLE.Dispatch
|| VT_ERROR || ''unsupported''
|| VT_BOOL || bool
|| VT_VARIANT || OLE.variant
|| VT_UNKNOWN || OLE.Unknown
|| VT_DECIMAL || OLE.decimal
|| VT_I1 || Int32.int
|| VT_UI1 || Word8.word
|| VT_UI2 || Word32.word
|| VT_UI4 || Word32.word
|| VT_I8 || IntInf.int
|| VT_UI8 || IntInf.int
|| VT_INT || Int32.int
|| VT_UINT || Word32.word
|| VT_VOID || unit
|| VT_HRESULT || ''unsupported''
|| VT_PTR(''vt'') || OLE.variant
|| VT_SAFEARRAY(''vt'') || [SML# type of ''vt''] OLE.safearray
|| VT_CARRAY || ''unsupported''
|| VT_USERDEFINED(TKIND_DISPATCH) || OLE.Dispatch
|| VT_USERDEFINED(TKIND_COCLASS) || OLE.Dispatch
|| VT_USERDEFINED(TKIND_ENUM) || Int32.int
|| VT_USERDEFINED(''other type'') || ''unsupported''
|| VT_LPSTR || ''unsupported''
|| VT_LPWSTR || ''unsupported''
|| VT_RECORD || ''unsupported''
|| VT_INT_PTR || ''unsupported''
|| VT_UINT_PTR || ''unsupported''
|| VT_FILETIME || ''unsupported''
|| VT_BLOB || ''unsupported''
|| VT_STREAM || ''unsupported''
|| VT_STORAGE || ''unsupported''
|| VT_STREAMED_OBJECT || ''unsupported''
|| VT_STORED_OBJECT || ''unsupported''
|| VT_BLOB_OBJECT || ''unsupported''
|| VT_CF || ''unsupported''
|| VT_CLSID || ''unsupported''
|| VT_BSTR_BLOB || ''unsupported''
|| VT_VECTOR || ''unsupported''
|| VT_ARRAY || ''unsupported''
|| VT_BYREF(''vt'') || OLE.variant

!!SAFEARRAY mapping.

COM [[SAFEARRAY|http://msdn.microsoft.com/en-us/library/ms221482.aspx]]
can describe multi-dimension arrays.
OLE/SML# maps a SAFEARRAY to '''OLE.safearray'''.
For example, a three-dimensional SAFEARRAY
VT_INT a[10][20][30]
is mapped to '''Int32.int OLE.safearray'''.
a : Int32.int OLE.safearray

An element of a SAFEARRAY
a[1][2][3]
is accessed as
OLE.SafeArray.sub (a, [1, 2, 3])

In addition to using OLE.SafeArray, you can access an safearray directly.
'''Int32.int OLE.safearray''' is a pair of an array of '''Int32.int''' and
a list of int.
(array, [10, 20, 30]) : Int32.int array * int list

The elements of an array are stored in column major order.
The first dimension changes first, and the last dimension changes last.

For example, an element of the above SAFEARRAY a
a[1][2][3]
is stored at the index of 3 * (10 * 20) + 2 * 10 + 1 = 621.
It can be accessed from SML# as
Array.sub(array, 621)

!method mapping.

A COM method which takes n arguments is mapped to a SML# function
which takes a tuple of n elements.

If a method is a void function returning nothing, it is mapped to a SML#
fuction which returns a unit.

||! COM method ||! SML# function
|| ''t0'' ''method''() || ''method'' : unit -> [''t0'']
|| ''t0'' ''method''(''t1'') || ''method'' : [''t1''] -> [''t0'']
|| ''t0'' ''method''(''t1'', ..., ''tn'') || ''method'' : [''t1''] * ... * [''tn''] -> [''t0'']

In this table,
""[''t'']
indicates the SML# datatype mapped from Variant type ''t''.

!!parameter mapping.

!!!optional parameter.
An optional parameter of type ''t'' is mapped to
""[''t''] option

!!![out] attribute.
If a parameter is annotated with [out] attribute, the type of the parameter
is mapped to '''OLE.variant ref'''.

!!!null reference parameter.
Use '''OLE.NullUnknown''' and '''OLE.NullDispatch''' to pass a null reference
in VT_UNKNOWN and VT_DISPATCH parameter.

Use '''EMPTY''' to pass a null pointer to other types in VT_VARIANT parameter.

!!property accessor

In addition to usual methods, COM objects expose three types of methods.
These are accessor methods for properties of COM objects.

The getter of a property ''p'' of type ''t'' is mapped to a SML# function
""get''p'' : unit -> [''t'']
The setter of a property ''p'' of type ''t'' is mapped to a SML# function
""set''p'' : [''t''] -> unit
The reference setter of a property ''p'' of type ''t'' is mapped to a SML# function
""setRef''p'' : [''t''] -> unit

!!Restriction.

OLE structure and OLE2SML ignore methods which satisfy any of following.

* any of its parameters has [ret] attribute.
* any of its parameters is variant type which is not included in OLE.variant.

!exception mapping.

If a COM object throws an exception in an invocation of its method from
OLE/SML#, an SML# exception
""OLE.OLEError(OLE.ComApplicationError ''detail'')
is raised to the caller in SML#.

If COM framework API function returns an error, an SML# exception
""OLE.OLEError(ComSystemError ''message'')
is raised to SML# world.

!Topics in OLE/SML#.

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