package DkSDKFFIOCaml_Std

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type
type ('msg, 'ptr) t

The type of connection to a DkSDK COM host platform.

The parameter type 'msg is the type of messages Capnp.MessageSig.MESSAGE.t sent to and from the host platform.

The parameter type 'ptr is the type of message pointer used to refer to opaque messages.

type method_id

The type of an identifier for a class or instance method

type closure_id

The type of identifier for the DkSDK::FFI::C::ICallable interface of a DkSDK COM instance object.

type ('msg, 'ptr) t_clazz

The type of a DkSDK COM class object

type ('msg, 'ptr, 'inst) t_inst

The type of a DkSDK COM instance object

type ('inst, 'msg, 'ptr) t_inst_id

The type of an identifier to a DkSDK COM instance object

type ('msg, 'ptr, 'inst, 'ret_inst) t_return

The type of return value for a generic method call. Typically as a author of DkSDK FFI COM classes you will manipulate the Make.t_author type, and then use a return function to convert the API type into this t type.

The return value is either a single Cap n' Proto message of type 'msg, or a new instance of type 'ret_inst. The type parameter 'inst is the type of the generic instance object whose method was called. Often, but not always, the 'ret_inst and the 'inst are the same.

val of_clazz : ('msg, 'ptr) t_clazz -> ('msg, 'ptr) t

Get the host platform connection used by a DkSDK COM class object

val of_inst : ('msg, 'ptr, 'inst) t_inst -> ('msg, 'ptr) t

Get the host platform connection used by a DkSDK COM instance object

val create_c : unit -> (Capnp.Message.rw Capnp__Message.Make(DkSDKFFIOCaml_Std__.Ffi_message.HostStorageC).Message.t, Capnp.Message.ro Capnp__Message.Make(DkSDKFFIOCaml_Std__.Ffi_message.HostStorageC).Slice.t option) t

create_c creates a COM connection to the C host platform.

Dksdk_ffi_ocaml_init.init_if_needed will automatically be called.

val pp_t_clazz : Stdlib.Format.formatter -> ('msg, 'ptr) t_clazz -> unit

pp_t_clazz fmt clazz prints the DkSDK COM class object clazz using formatter fmt

val pp_t_inst : Stdlib.Format.formatter -> ('msg, 'ptr, 'inst) t_inst -> unit

pp_t_inst fmt inst prints the DkSDK COM instance object inst using formatter fmt

val msg_of_closure_id : ('msg, 'ptr) t -> closure_id -> 'msg

msg_of_closure_id com closure_id gets the StandardSchemas.ComObject message for the closure identifier closure_id.

val closure_id_of_icallable : ('msg, 'ptr, 'inst) t_inst -> closure_id option

closure_id_of_icallable instance gets the closure identifier for instance if instance has a "DkSDK::FFI::C::ICallable" interface.

If there is no "DkSDK::FFI::C::ICallable" interface, then None is returned.

val closure_id_of_icallable_exn : ?what:string -> ('msg, 'ptr, 'inst) t_inst -> closure_id

closure_id_of_icallable_exn ?what instance gets the closure identifier for instance if instance has a "DkSDK::FFI::C::ICallable" interface.

what is an optional noun or noun phrase that describes which instance is being checked.

If there is no "DkSDK::FFI::C::ICallable" interface, then a Not_found exception is raised that includes the what noun or noun phrase.

val borrow_class_until_finalized : ('msg, 'ptr) t -> string -> ('msg, 'ptr) t_clazz

borrow_class_until_finalized t classname borrows a reference to the DkSDK COM class object named classname from the DkSDK COM registry.

If the class does not exist, an Stdlib.Invalid_argument exception is raised.

The borrowing ends when the OCaml garbage collector determines there are no more OCaml references to the class object. However, the class object will not be terminated until there are no references in the host platform, including the one reference maintained by the DkSDK COM registry.

val method_id : string -> method_id

method_id name returns the method identifier for the method named name.

type ('msg, 'ptr, 'inst) instance_factory = ('msg, 'ptr, 'inst) t_inst -> 'inst

The type of instance factory of shape let f com_object_id = ... which returns a new instance.

val call_class_method : ('msg, 'ptr) t_clazz -> method_id -> 'msg -> 'ptr

call_class_method clazz method_id args calls the static (aka. class) method identified by method_id on the DkSDK class object clazz, with the Cap n' Proto message args as the method arguments.

The generic class method for method_id must return a GenericReturn with the ``value`` union field set. An Invalid_argument is raised if a ``newObject`` union field is set instead.

The return value from call_class_method will be a Cap n' Proto message pointer. You can open your schema and use Reader.of_pointer to cast the pointer to any Cap n' Proto message type in your schema. If you use a message type that is different from the true return value message type, you will get a garbled message, although you should not get any segmentation faults.

val call_class_constructor : ('msg, 'ptr) t_clazz -> method_id -> ('msg, 'ptr, 'inst) instance_factory -> 'msg -> 'inst

call_class_constructor clazz method_id new_inst args constructs a new instance by calling a class method.

The sequence is:

  1. Calls the class (aka. static) method identified by method_id on the DkSDK class object clazz with the arguments args
  2. The resulting GenericReturn is validated to see if it has the newObject union set. If not, an Invalid_argument is raised.
  3. The newObject has a COM object identifier (the new COM object) that is converted to an instance with new_inst.

When the OCaml garbage collector determines there are no more OCaml references to the new instance, the reference count of the new COM object is decremented.

val call_instance_method : ('msg, 'ptr, 'inst) t_inst -> method_id -> 'msg -> 'ptr

call_instance_method inst method_id args call the instance method identified by method_id on the DkSDK instance object inst, with the Cap n' Proto message args as the method arguments.

The generic instance method for method_id must return a GenericReturn with the ``value`` union field set. An Invalid_argument is raised if a ``newObject`` union field is set instead.

The return value from call_instance_method will be a Cap n' Proto message pointer. You can open your schema and use Reader.of_pointer to cast the pointer to any Cap n' Proto message type in your schema. If you use a message type that is different from the true return value message type, you will get a garbled message, although you should not get any segmentation faults.

val call_instance_constructor : ('msg, 'ptr, 'inst) t_inst -> method_id -> ('msg, 'ptr, 'inst) instance_factory -> 'msg -> 'inst

call_instance_constructor inst method_id new_inst args constructs a new instance by calling an instance method.

A clone or duplicate instance method would be an example of an instance constructor.

The sequence is:

  1. Calls the instance method identified by method_id on the DkSDK instance object inst with the arguments args
  2. The resulting GenericReturn is validated to see if it has the newObject union set. If not, an Invalid_argument is raised.
  3. The newObject has a COM object identifier (the new COM object) that is converted to an instance with new_inst.

When the OCaml garbage collector determines there are no more OCaml references to the new instance, the reference count of the new COM object is decremented.

val instance : ('msg, 'ptr) t -> ('msg, 'ptr) t_clazz -> 'inst -> ('inst, 'msg, 'ptr) t_inst_id

instance t clazz inst wraps an instance inst of class clazz and registers the wrapped instance as a DkSDK COM object.

The instance will be finalized when all the following conditions are true:

1. There are no more OCaml references to the instance inst. 2. All DkSDK COM references to the instance have been released.

val closure : ('msg, 'ptr) t -> ('inst -> 'msg -> ('msg, 'ptr, 'inst, 'ret_inst) t_return) -> closure_id

closure t f wraps a callback function f self msg so the callback can be registered as a DkSDK COM instance object that implements DkSDK::FFI::C::ICallable.

closure creates an ICallable DkSDK COM instance object from the function f self args, and returns a 2 x 128-bit binary object reference to the closure.

There is no way for user code in this version of DkSDK to directly access self from a closure. Your function should be defined to ignore the self as in let f _ args = .... You can of course use ComClassBuilder which has instance methods that are essentially closures but have self bound to the instance.

Use Com.MakeReturn.return_from_closure to gain return a message from your function f. Here is an example:

open DkSDKFFIOCaml_Std
open Com.MakeReturn (ComMessage.C)
open ComStandardSchema.Make (ComMessage.C)

let closure_id =
  Com.closure com (fun _ args ->
    let bldr = Builder.St.init_root () in
    Builder.St.i1_set bldr "Hello World";
    return_from_closure bldr
  )

The closure will be finalized when all the following conditions are true:

1. There are no more OCaml references to the function f. 2. All DkSDK COM references to the closure have been released.

For example, the DkSDK COM object may be a user interface "Window" which has a "Press Me" button that can be pressed. You have given a callback function to the Window by using closure. Typically when the Window is closed all of its callbacks should be released, but the precise timing is the responsibility of the Window.

Authoring Returning Values

The MakeReturn module mediates how user code returns a value from a DkSDK COM method.

It is automatically opened if you do open Com.MakeClassBuilder (ComMessage.C). However, if you directly need to use it you can open it with:

open DkSDKFFIOCaml_Std
open Com.MakeReturn (ComMessage.C)

We designed the types t_author and return to write simple, readable and numerous DkSDK COM classes in OCaml.

The first parameter to your methods is a function of type return that can be used like:

open Com.MakeReturn (ComMessage.C)

(* An ordinary method. *)
let method1      v args = v (Capnp (*...*))

(* A constructor where you represent your instances as objects *)
let constructor1 v args = v (New (new someclass (*...*)))

(* A constructor where you represent your instances as records *)
let constructor2 v args = v (New (Something.{field1=(*...*)}))

(* A constructor where you represent your instances as first class modules *)
let constructor3 v args = v (New (module (*...*)))

(* A constructor where you represent your instances as strings (but why?) *)
let constructor4 v args = v (New ("some string"))

Above we used the name v which is a convention in OCaml for any function which lifts one type into a more canonical type. However, if your team is familiar with traditional languages, or you are producing public-facing documentation, you may want to use the name return as in:

let method1 return args = return (Capnp (*...*))

The following alternative possibilities were rejected:

  1. let method1 v_msg v_new args = v_msg (*...*). This form will cause compiler warnings about unused parameters. You would either need to write let method1 v_msg _ = v_msg (*...*) or let method1 v_msg v_new = ignore v_new; v_msg (*...*).
  2. let method1 ~return args = return (Capnp (*...*)). This form won't let you shorten the return into v without an unwieldy rename let method1 ~(return=v) args = v (Capnp (*...*)) which barely saves space. Space is essential when binding many classes and methods from another programming language.
module MakeReturn (M : Capnp.MessageSig.S) : sig ... end
module MakeClassBuilder (M : Capnp.MessageSig.S) : sig ... end
OCaml

Innovation. Community. Security.