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.
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.rwCapnp__Message.Make(DkSDKFFIOCaml_Std__.Ffi_message.HostStorageC).Message.t,
Capnp.Message.roCapnp__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.
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.
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.
call_class_constructor clazz method_id new_inst args constructs a new instance by calling a class method.
The sequence is:
Calls the class (aka. static) method identified by method_id on the DkSDK class object clazz with the arguments args
The resulting GenericReturn is validated to see if it has the newObject union set. If not, an Invalid_argument is raised.
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.
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:
Calls the instance method identified by method_id on the DkSDK instance object inst with the arguments args
The resulting GenericReturn is validated to see if it has the newObject union set. If not, an Invalid_argument is raised.
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.
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:
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 (*...*).
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.