Special Structures
This section describes the SML structures that are not generated by introspection, or deviate significantly from their introspected form.
Giraffe
The top-level structure Giraffe provides general purpose utilities. Currently, the structure provides functions for exiting an application that are more convenient than the Basis Library alternatives.
structure Giraffe :> GIRAFFE
signature GIRAFFE =
sig
(**
* `exit status` exits the process where the exit status is the lower
* 8 bits of (the two's complement representation of) `status`.
*)
val exit : LargeInt.int -> 'a
(**
* `error status errMsgs` outputs `errMsgs` to the standard error,
* flushes the standard error and exits the process using `exit status`.
*)
val error : LargeInt.int -> string list -> 'a
end
ValueAccessor
This structure is unlikely to be needed by an application because there is rarely a need to use a GObject.Value instance directly, especially as the structure Property provides a high-level type safe interface for properties.
The top-level structure ValueAccessor is included with the structure GObject and provides support for working with GObject.Value records directly. The structure defines the type 'a ValueAccessor.t that encapsulates typed access to a GObject.Value record. This does not provide type safe access to a GObject.Value record but each accessor links an SML type and GObject dynamic type (represented by GObject.Type) allowing type-safe wrappers to be created around a GObject.Value record.
structure ValueAccessor :>
VALUE_ACCESSOR
where type type_t = GObjectType.t
where type value_t = GObjectValueRecord.t
where type C.value_v = GObjectValueRecord.C.v
signature VALUE_ACCESSOR =
sig
type 'a t
type type_t
type value_t
val new : 'a t -> 'a -> value_t
val get : 'a t -> value_t -> 'a
val set : 'a t -> value_t -> 'a -> unit
val gtype : 'a t -> type_t
val map : ('a -> 'b) * ('b -> 'a) -> 'a t -> 'b t
structure C :
sig
type value_v
val createAccessor :
{
getType : unit -> type_t,
getValue : value_v -> 'a,
setValue : (value_v, 'a) pair -> unit
}
-> 'a t
val gtype : 'a t -> unit -> type_t
val get : 'a t -> value_v -> 'a
val set : 'a t -> value_v -> 'a -> unit
val init : value_v -> type_t -> unit
val isValue : value_v -> bool
end
structure Types :
sig
val boolean : bool t
val int : LargeInt.int t
val uint : LargeInt.int t
val long : LargeInt.int t
val ulong : LargeInt.int t
val int64 : LargeInt.int t
val uint64 : LargeInt.int t
val float : real t
val double : real t
val char : char t
val string : string t
val stringOpt : string option t
end
end
Signal
The top-level structure Signal is included with the structure GObject and provides a high-level type safe representation of a signal, ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) Signal.t, and associated operations.
The internal representation of type Signal.t is exposed to work around the value restriction when declaring a signal value. (A parameter of type Signal.t always contains a variable.) Typically, applications do not declare signals so the internal representation can be ignored.
structure Signal :>
SIGNAL
where type 'a object_class = 'a GObjectObjectClass.class
where type ('object_class, 'get, 'set, 'init) property_t =
('object_class, 'get, 'set, 'init) Property.t
where type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller =
('arg_r, 'arg_w, 'res_r, 'res_w) GObjectClosure.marshaller
signature SIGNAL =
sig
type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller
(**
* Representation of a signal
*
* The type `('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t`
* represents a signal of the class represented by the type
* `'object_class` where
*
* 'arg_e -> 'res_e
* is the type of a function that emits the signal and
*
* 'arg_h -> 'res_h
* is the type of a function that handles the signal.
*
* The type parameters `'arg_e`, `'arg_h`, `'res_h` and `'res_e` capture
* the type and direction of the signal arguments and the type of the
* signal return value as follows:
*
* `'arg_e` and `'arg_h` are instantiated to the types of the
* signal 'in' and 'inout' arguments;
*
* `'res_e` and `'res_h` are instantiated to the types of the
* signal return value and 'out' and 'inout' arguments.
*
* The 'e' and 'h' variants differ in whether they allow an object of any
* subclass or not and whether they allow an instance of any field of a
* union or not.
*
* Ideally, the type `('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t`
* would be abstract and a function defined to construct values of the
* type. However, the resulting value always contains a type variable in
* the parameter `'object_class` to allow the type of any subclass to
* unify with it. The application of the construction function is a non-
* expansive expression so the result cannot be a value containing a
* type variable due to the value restriction. The usual work around
* for the value restriction is to defer evaluation, so a signal would
* have the type `unit -> ('object_class, ...) t` but this is not done.
* Instead, the type is not abstract and its concrete representation - a
* record - enables a value to be written as an expansive expression,
* thereby avoiding the value restriction.
*)
type ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t =
{
name : string,
detail : string,
marshaller :
unit
-> (
(unit, 'arg_h) pair,
('object_class, 'arg_e) pair,
'res_e,
'res_h
)
marshaller
}
val conv :
('a -> 'b)
-> ('b, 'arg_e, 'arg_h, 'res_h, 'res_e) t
-> ('a, 'arg_e, 'arg_h, 'res_h, 'res_e) t
type 'a object_class
val emit :
'a object_class
-> ('a object_class, 'arg_e, 'b, 'c, 'res_e) t
-> 'arg_e -> 'res_e
type handler_id
val connect :
'a object_class
-> ('a object_class, 'b, 'arg_h, 'res_h, 'c) t * ('arg_h -> 'res_h)
-> handler_id
val connectAfter :
'a object_class
-> ('a object_class, 'b, 'arg_h, 'res_h, 'c) t * ('arg_h -> 'res_h)
-> handler_id
val handlerBlock : 'a object_class -> handler_id -> unit
val handlerUnblock : 'a object_class -> handler_id -> unit
val handlerDisconnect : 'a object_class -> handler_id -> unit
val handlerIsConnected : 'a object_class -> handler_id -> bool
val detail : ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t -> string
val withDetail :
('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t * string
-> ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t
type ('object_class, 'get, 'set, 'init) property_t
val withPropDetail :
('a object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t
* ('a object_class, 'get, 'set, 'init) property_t
-> ('a object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t
end
ChildSignal
The top-level structure ChildSignal is included with the structure Gtk and provides convenience functions that connect a handler to a signal of a non Gtk.Widget object where the handler is disconnected when a Gtk.Widget object receives the “destroy” signal.
This is intended to be used for connecting a handler to a signal of an object where the handler function directly or indirectly references the object. In this scenario, there is a reference cycle that is not visible to the SML compiler's garbage collector. There is no issue for a signal of a Gtk.Widget object because the “destroy” signal causes any signal handlers to be disconnected. For a non Gtk.Widget object, which does not have a “destroy” signal, the signal handler must be explicitly disconnected to remove the reference cycle. The functions in this structure simplify this when there is a widget whose lifespan can be used as the lifespan of the handler function (and there typically is such a widget).
structure ChildSignal :>
CHILD_SIGNAL
where type 'a widget_class = 'a GtkWidgetClass.class
signature CHILD_SIGNAL =
sig
type 'a widget_class
val connect :
'a widget_class
-> 'b GObject.ObjectClass.class
-> ('b GObject.ObjectClass.class, 'c, 'arg_h, 'res_h, 'd) Signal.t * ('arg_h -> 'res_h)
-> unit
val connectAfter :
'a widget_class
-> 'b GObject.ObjectClass.class
-> ('b GObject.ObjectClass.class, 'c, 'arg_h, 'res_h, 'd) Signal.t * ('arg_h -> 'res_h)
-> unit
end
Property
The top-level structure Property is included with the structure GObject and provides a high-level type safe representation of a property, ('object_class, 'get, 'set, 'init) Property.t, and associated operations.
structure Property :>
PROPERTY
where type type_t = GObjectType.t
where type value_v = GObjectValueRecord.C.v
where type 'a object_class = 'a GObjectObjectClass.class
where type 'a binding_class = 'a GObjectBindingClass.class
signature PROPERTY =
sig
type type_t
type value_v
type 'a object_class
type 'a binding_class
(**
* Representation of a property
*
* The type `('object_class, 'get, 'set, 'init) t` represents a property
* of an object whose class is represented by the type `'object_class`.
* The type parameters `'get`, `'set` and `'init` capture the possible
* access modes as follows so that type checking ensures mode safety:
*
* 'get is instantiated to:
*
* unit -> 'r
* if a value of type 'r can be read from the property
*
* unit
* if the property is not readable
*
* 'set is instantiated to:
*
* 'w -> unit
* if a value of type 'w can be written to the property
* after object construction
*
* unit
* if the property is not writable after object construction
*
* 'init is instantiated as for 'set but according to whether
* a value of type 'w can be set during object construction.
*
* Ideally, the type `('object_class, 'get, 'set, 'init) t` would be
* abstract and a function defined to construct values of the type.
* However, the resulting value always contains a type variable in the
* parameter `'object_class` to allow the type of any subclass to unify
* with it. The application of the construction function is a non-
* expansive expression so the result cannot be a value containing a
* type variable due to the value restriction. The usual work around
* for the value restriction is to defer evaluation, so a property would
* have the type `unit -> ('object_class, 'get, 'set, 'init) t` but this
* is not done. Instead, the type is not abstract and its concrete
* representation - a record - enables a value to be written as an
* expansive expression, thereby avoiding the value restriction.
* However, the type parameter `'object_class` is a phantom type which
* must be therefore be mentioned in the concrete representation
* (otherwise it imposes no type constraint). An argument of this
* type can be added to the `get` and `set` functions because they
* require an object instance to operate on therefore there is always
* a value available to use as the witness for the type. Note that the
* field `gtype` must defer evaluation because some GObject types are not
* determined until run-time. This is convenient because it allows the
* value to be defined by a non-expansive expression without falling foul
* of the value restriction.
*)
type ('object_class, 'get, 'set, 'init) t =
{
name : string,
gtype : unit -> type_t,
get : 'object_class -> value_v -> 'get,
set : 'object_class -> value_v -> 'set,
init : value_v -> 'init
}
val conv :
('a -> 'b)
-> ('b, 'get, 'set, 'init) t
-> ('a, 'get, 'set, 'init) t
(**
* Access to a property
*)
val get : ('a object_class, unit -> 'r, 'b, 'c) t -> 'a object_class -> 'r
val set : ('a object_class, 'b, 'w -> unit, 'c) t -> 'w -> 'a object_class -> unit
(**
* Initial value of a property, for use with `GObject.Object.new`
*)
type 'object_class init_t
val init : ('object_class, 'a, 'b, 'w -> unit) t -> 'w -> 'object_class init_t
val initName : 'object_class init_t -> string
val initValue : 'object_class init_t -> value_v -> unit
(**
* Binding two properties
*
* These functions provide a type safe interface to
* `GObject.Object.bindProperty[Full]`. For the non-full versions, where
* the conversion is implicit, it is assumed that if two properties have
* the same SML type but different GObject types, then the value of one
* can be transformed to the value of the other.
*
* In every function, the `bool` argument determines whether the
* properties are synchronized on creation.
*)
val bind :
'a object_class
* ('a object_class, unit -> 'c, 'set, 'init) t
* 'b object_class
* ('b object_class, 'get, 'c -> unit, 'init) t
* bool
-> base binding_class
val bindBidir :
'a object_class
* ('a object_class, unit -> 'c, 'd -> unit, 'init) t
* 'b object_class
* ('b object_class, unit -> 'd, 'c -> unit, 'init) t
* bool
-> base binding_class
val bindInvertBool :
'a object_class
* ('a object_class, unit -> bool, 'set, 'init) t
* 'b object_class
* ('b object_class, 'get, bool -> unit, 'init) t
* bool
-> base binding_class
val bindBidirInvertBool :
'a object_class
* ('a object_class, unit -> bool, bool -> unit, 'init) t
* 'b object_class
* ('b object_class, unit -> bool, bool -> unit, 'init) t
* bool
-> base binding_class
val bindFull :
'a object_class
* ('a object_class, unit -> 'c, 'set, 'init) t
* 'b object_class
* ('b object_class, 'get, 'd -> unit, 'init) t
* bool
* ('c -> 'd)
-> base binding_class
val bindFullBidir :
'a object_class
* ('a object_class, unit -> 'c, 'f -> unit, 'init) t
* 'b object_class
* ('b object_class, unit -> 'e, 'd -> unit, 'init) t
* bool
* ('c -> 'd)
* ('e -> 'f)
-> base binding_class
end
ClassifyEvent
The top-level structure ClassifyEvent is included with the structure Gdk and provides a data type ClassifyEvent.t and a function ClassifyEvent.classify to return the current field of a Gdk.Event union according to its discriminant.
structure ClassifyEvent :>
CLASSIFY_EVENT
where type 'a event_union = 'a GdkEvent.union
where type event_any_t = GdkEventAnyRecord.t
where type event_key_t = GdkEventKeyRecord.t
where type event_button_t = GdkEventButtonRecord.t
where type event_scroll_t = GdkEventScrollRecord.t
where type event_motion_t = GdkEventMotionRecord.t
where type event_expose_t = GdkEventExposeRecord.t
where type event_visibility_t = GdkEventVisibilityRecord.t
where type event_crossing_t = GdkEventCrossingRecord.t
where type event_focus_t = GdkEventFocusRecord.t
where type event_configure_t = GdkEventConfigureRecord.t
where type event_property_t = GdkEventPropertyRecord.t
where type event_selection_t = GdkEventSelectionRecord.t
where type event_dnd_t = GdkEventDNDRecord.t
where type event_proximity_t = GdkEventProximityRecord.t
where type event_window_state_t = GdkEventWindowStateRecord.t
where type event_setting_t = GdkEventSettingRecord.t
where type event_owner_change_t = GdkEventOwnerChangeRecord.t
where type event_grab_broken_t = GdkEventGrabBrokenRecord.t
where type event_any_record_event = GdkEventAnyRecord.event
where type event_key_record_event = GdkEventKeyRecord.event
where type event_button_record_event = GdkEventButtonRecord.event
where type event_scroll_record_event = GdkEventScrollRecord.event
where type event_motion_record_event = GdkEventMotionRecord.event
where type event_expose_record_event = GdkEventExposeRecord.event
where type event_visibility_record_event = GdkEventVisibilityRecord.event
where type event_crossing_record_event = GdkEventCrossingRecord.event
where type event_focus_record_event = GdkEventFocusRecord.event
where type event_configure_record_event = GdkEventConfigureRecord.event
where type event_property_record_event = GdkEventPropertyRecord.event
where type event_selection_record_event = GdkEventSelectionRecord.event
where type event_dnd_record_event = GdkEventDNDRecord.event
where type event_proximity_record_event = GdkEventProximityRecord.event
where type event_window_state_record_event = GdkEventWindowStateRecord.event
where type event_setting_record_event = GdkEventSettingRecord.event
where type event_owner_change_record_event = GdkEventOwnerChangeRecord.event
where type event_grab_broken_record_event = GdkEventGrabBrokenRecord.event
signature CLASSIFY_EVENT =
sig
type 'a event_union
type event_any_t
type event_key_t
type event_button_t
type event_touch_t
type event_scroll_t
type event_motion_t
type event_expose_t
type event_visibility_t
type event_crossing_t
type event_focus_t
type event_configure_t
type event_property_t
type event_selection_t
type event_dnd_t
type event_proximity_t
type event_window_state_t
type event_setting_t
type event_owner_change_t
type event_grab_broken_t
type event_touchpad_swipe_t
type event_touchpad_pinch_t
type event_pad_button_t
type event_pad_axis_t
type event_pad_group_mode_t
type event_any_record_event
type event_key_record_event
type event_button_record_event
type event_touch_record_event
type event_scroll_record_event
type event_motion_record_event
type event_expose_record_event
type event_visibility_record_event
type event_crossing_record_event
type event_focus_record_event
type event_configure_record_event
type event_property_record_event
type event_selection_record_event
type event_dnd_record_event
type event_proximity_record_event
type event_window_state_record_event
type event_setting_record_event
type event_owner_change_record_event
type event_grab_broken_record_event
type event_touchpad_swipe_record_event
type event_touchpad_pinch_record_event
type event_pad_button_record_event
type event_pad_axis_record_event
type event_pad_group_mode_record_event
datatype t =
ANY of event_any_t * event_any_record_event
| KEY of event_key_t * event_key_record_event
| BUTTON of event_button_t * event_button_record_event
| TOUCH of event_touch_t * event_touch_record_event
| SCROLL of event_scroll_t * event_scroll_record_event
| MOTION of event_motion_t * event_motion_record_event
| EXPOSE of event_expose_t * event_expose_record_event
| VISIBILITY of event_visibility_t * event_visibility_record_event
| CROSSING of event_crossing_t * event_crossing_record_event
| FOCUS of event_focus_t * event_focus_record_event
| CONFIGURE of event_configure_t * event_configure_record_event
| PROPERTY of event_property_t * event_property_record_event
| SELECTION of event_selection_t * event_selection_record_event
| DND of event_dnd_t * event_dnd_record_event
| PROXIMITY of event_proximity_t * event_proximity_record_event
| WINDOW_STATE of event_window_state_t * event_window_state_record_event
| SETTING of event_setting_t * event_setting_record_event
| OWNER_CHANGE of event_owner_change_t * event_owner_change_record_event
| GRAB_BROKEN of event_grab_broken_t * event_grab_broken_record_event
| TOUCHPAD_SWIPE of event_touchpad_swipe_t * event_touchpad_swipe_record_event
| TOUCHPAD_PINCH of event_touchpad_pinch_t * event_touchpad_pinch_record_event
| PAD_BUTTON of event_pad_button_t * event_pad_button_record_event
| PAD_AXIS of event_pad_axis_t * event_pad_axis_record_event
| PAD_GROUP_MODE of event_pad_group_mode_t * event_pad_group_mode_record_event
val classify : 'a event_union -> t option
end
Internal
The structures in this section should not be needed by applications but are listed for reference.
GObjectType
The top-level structure GObjectType provides the implementation of the GObject.Type structure. In the GObject namespace, introspection metadata defines the type named Type as an alias for gsize which would result in GObject.Type.t being equivalent to the type GSize.t. This structure makes GObject.Type.t an abstract scalar equality type to prevent use as an integer and provides operations and constructors for this type.
structure GObjectType :> G_OBJECT_TYPE
signature G_OBJECT_TYPE =
sig
include C_SCALAR_EQ_NULL
val isValueType : t -> bool
val isA : t * t -> bool
val name : t -> string
val fromName : string -> t option
val invalid : unit -> t
val none : unit -> t
val interface : unit -> t
val char : unit -> t
val uchar : unit -> t
val boolean : unit -> t
val int : unit -> t
val uint : unit -> t
val long : unit -> t
val ulong : unit -> t
val int64 : unit -> t
val uint64 : unit -> t
val enum : unit -> t
val flags : unit -> t
val float : unit -> t
val double : unit -> t
val string : unit -> t
val pointer : unit -> t
val boxed : unit -> t
val param : unit -> t
val object : unit -> t
val gtype : unit -> t
val variant : unit -> t
val paramChar : unit -> t
val paramUChar : unit -> t
val paramBoolean : unit -> t
val paramInt : unit -> t
val paramUInt : unit -> t
val paramLong : unit -> t
val paramULong : unit -> t
val paramInt64 : unit -> t
val paramUInt64 : unit -> t
val paramUnichar : unit -> t
val paramEnum : unit -> t
val paramFlags : unit -> t
val paramFloat : unit -> t
val paramDouble : unit -> t
val paramString : unit -> t
val paramParam : unit -> t
val paramBoxed : unit -> t
val paramPointer : unit -> t
val paramValueArray : unit -> t
val paramObject : unit -> t
val paramOverride : unit -> t
val paramGType : unit -> t
val paramVariant : unit -> t
end
GObjectValue
The top-level structure GObjectValue provides the implementation of the GObject.Value structure. This structure excludes the introspected get and set functions because the ValueAccessor structure is used instead. Accessors for the fundamental types are provided in the structure ValueAccessor.Types.
The function GObjectValue.reset deviates from its introspected form by returning unit rather than its argument.
The function GObjectValue.new is provided in addition to the introspected functions.
structure GObjectValue :>
G_OBJECT_VALUE
where type t = GObjectValueRecord.t
where type type_t = GObjectType.t
signature G_OBJECT_VALUE =
sig
type t
type type_t
val getType : unit -> type_t
val new : unit -> t (* new value is initialized to zero *)
val copy :
t
-> t
-> unit
val fitsPointer : t -> bool
val init :
t
-> type_t
-> unit
val reset : t -> unit
val transform :
t
-> t
-> bool
val unset : t -> unit
val typeCompatible : type_t * type_t -> bool
val typeTransformable : type_t * type_t -> bool
val holds : type_t -> t -> bool
val gTypeOf : t -> type_t
val isValue : t -> bool
end
GObjectClosure
The top-level structure GObjectClosure provides the implementation of the GObject.Closure structure. This structure excludes most of the introspected entities and provides a constructor GObjectClosure.new that creates a GObject closure that wraps an SML function of type 'arg_r -> 'res_w given an SML marshaller of type ('arg_r, 'arg_w, 'res_r, 'res_w) ClosureMarshal.marshaller.
structure GObjectClosure :>
G_OBJECT_CLOSURE
where type t = GObjectClosureRecord.t
where type type_t = GObjectType.t
where type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller = ('arg_r, 'arg_w, 'res_r, 'res_w) ClosureMarshal.marshaller
signature G_OBJECT_CLOSURE =
sig
type t
type type_t
type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller
val getType : unit -> type_t
val new : ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller * ('arg_r -> 'res_w) -> t
val invalidate : t -> unit
end
ClosureMarshal
The top-level structure ClosureMarshal is included with the structure GObject and provides functions to construct an SML marshaller for a GObject closure. An SML marshaller is bidirectional: given an SML marshaller of type ('arg_r, 'arg_w, 'res_r, 'res_w) ClosureMarshal.marshaller, a GObject closure can be called by an SML function of type 'arg_w -> 'res_r and an SML function of type 'arg_r -> 'res_w can be called by a GObject closure.
structure ClosureMarshal :>
CLOSURE_MARSHAL
where type 'a accessor = 'a ValueAccessor.t
where type C.value_v = GObjectValueRecord.C.v
where type C.value_array_v = GObjectValueRecordCArrayN.C.non_opt GObjectValueRecordCArrayN.C.p
infixr &&&
signature CLOSURE_MARSHAL =
sig
type 'a accessor
structure C :
sig
type value_v
type value_array_v
end
type ('r, 'w) arg
type ('r, 'w) res
type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller =
{
getArg : C.value_array_v -> 'arg_r,
setArg : C.value_array_v -> 'arg_w -> unit,
getRes : C.value_array_v * C.value_v -> 'res_r,
setRes : C.value_array_v * C.value_v -> 'res_w -> unit,
initPars : (C.value_v -> unit) vector,
initRet : C.value_v -> unit
}
val &&&> :
('a_r, 'a_w) arg * ('b_r, 'b_w) arg
-> (('a_r, 'b_r) pair, ('a_w, 'b_w) pair) arg
val &&& :
('a_r, 'a_w) res * ('b_r, 'b_w) res
-> (('a_r, 'b_r) pair , ('a_w, 'b_w) pair) res
val ---> :
('arg_r, 'arg_w) arg * ('res_r, 'res_w) res
-> ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller
val parInst : 'a accessor -> (unit, 'a) arg
val parIn : int -> 'a accessor -> ('a, 'a) arg
val parOut : int -> 'a accessor -> ('a, 'a) res
val ret : 'a accessor -> ('a, 'a) res
val retVoid : (unit, unit) res
val map :
('arg1_r -> 'arg2_r)
* ('arg2_w -> 'arg1_w)
* ('res1_r -> 'res2_r)
* ('res2_w -> 'res1_w)
-> ('arg1_r, 'arg1_w, 'res1_r, 'res1_w) marshaller
-> ('arg2_r, 'arg2_w, 'res2_r, 'res2_w) marshaller
type callback
val makeCallback :
('arg_r, 'arg_w, 'res_r, 'res_w) marshaller * ('arg_r -> 'res_w)
-> callback
…
end