dksdk_ffi_c/cls_generic.h¶
Defines
-
DK_CLS_MAX_FAT_POINTER_SZ¶
-
DK_CLS_ERR_DEAD_OBJECT¶
The object was dead due to a destructor call, yet an instance method was called.
-
DK_IIDSTR_GENERIC_CLASS¶
The interface identifier for the class object
dksdk_ffi_c_cls_generic
.
Typedefs
-
typedef uint32_t meth31¶
A method identifier.
-
typedef int DK_MESSAGE_BUILDER(struct dksdk_ffi *ffi, struct capn *messageAddr)¶
Create a message that can be used to build a return value message from a method call, or an arguments message to a method call.
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param messageAddr:
The address of a
struct capn
that, on success, will be set to the the newly constructed message.- Return:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi or messageAddr are NULL
DKSDK_FFI_ERR_INVALID_STATE when there is not enough memory
-
typedef int DK_CLASS_METHOD(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic_class_fields *ctor, const struct dksdk_ffi_c_cls_closure_data *closure, struct dksdk_ffi_c_cls_generic_call_ctx *ctx, struct dk_cls_capnp_args *args)¶
A class (also known as static) method, including but not limited to a class constructor method.
The return value for the class method must comply with Returning results from methods.
Requirements¶
The class method has a post-condition. It must release the
args
parameter with dksdk_ffi_c_cls_release_args, even if the method exited in error.The
args
parameter must not be released before the arguments have been parsed and used.
The timing of the dksdk_ffi_c_cls_release_args can be done whenever it is convenient. Choices include:
Releasing before the method exits
If the method queues up work in an event queue, releasing when the work is removed from the event queue
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param ctor:
[in] A constructor helper object. If the method is a constructor method, this constructor helper object can be used in dksdk_ffi_c_cls_generic_new_instance to create a new instance.
- Param closure:
[in] Closure captured when the class method was defined.
- Param ctx:
[in] Context for the call, including a message for a return value. The return value is an already initialized Cap n' Proto message. As an optimization the return value message may have one or more of its segments pre-allocated on the stack. Some messages may not let you exceed the capacity of pre-allocated segments; if so, you must return DKSDK_FFI_ERR_INVALID_STATE.
- Param args:
[in] Cap n' Proto message whose root structure contains the arguments for the method. May be NULL.
- Return:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT on error
DKSDK_FFI_ERR_INVALID_STATE on error
any positive, non-zero number for a user error code
-
typedef int DK_CLASS_DESTRUCTOR(struct dksdk_ffi *ffi, const struct dksdk_ffi_c_cls_closure_data *closure, const dksdk_ffi_uuid *clsid, struct dk_cls_capnp_args *args)¶
A destructor on an class.
Once a destructor is called, it is DkSDK FFI's responsibility to ensure no other destructor method will be called again for that class. In other words, the destructor is idempotent and will not create a double free bug. When a second destructor is called (or the same destructor is called twice), DkSDK FFI will ignore the second destructor call.
Requirements¶
The instance method has a post-condition. It must release the
args
parameter with dksdk_ffi_c_cls_release_args, even if the method exited in error.The
args
parameter must not be released before the arguments have been parsed and used.
The timing of the dksdk_ffi_c_cls_release_args can be done whenever it is convenient. Choices include:
Releasing before the method exits
If the method queues up work in an event queue, releasing when the work is removed from the event queue
Why Destructor Arguments?¶
Although it is unusual for a programming language to have destructor arguments, DkSDK FFI's API mandates that arguments are passed to destructors. That is because method identifiers have a broad range and can map to destructors, instance methods or other types of methods. When you allocate method arguments something (the method, including destructor method) is responsible for de-allocating those arguments.
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param closure:
[in] Closure captured when the class destructor was defined.
- Param clsid:
[in] The CLSID that is being destroyed.
- Param args:
[in] Cap n' Proto message whose root structure contains the arguments for the destructor method. May be NULL.
- Return:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT on error
DKSDK_FFI_ERR_INVALID_STATE on error
any positive, non-zero number for a user error code
-
typedef int DK_INSTANCE_METHOD(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic_instance *instance, const struct dksdk_ffi_c_cls_closure_data *closure, struct dksdk_ffi_c_cls_generic_call_ctx *ctx, struct dk_cls_capnp_args *args)¶
A method on an instance object.
The return value for the instance method must comply with Returning results from methods.
Requirements¶
The instance method has a post-condition. It must release the
args
parameter with dksdk_ffi_c_cls_release_args, even if the method exited in error.The
args
parameter must not be released before the arguments have been parsed and used.
The timing of the dksdk_ffi_c_cls_release_args can be done whenever it is convenient. Choices include:
Releasing before the method exits
If the method queues up work in an event queue, releasing when the work is removed from the event queue
See also
DK_CLASS_METHOD
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param instance:
[in] The instance values of the instance object. Its
ptr
field has the pointer to the host object. The lifetime ofinstance
is only to the end of the instance method.- Param closure:
[in] Closure captured when the instance method was defined.
- Param ctx:
[in] Context for the call, including a message for a return value. The return value is an already initialized Cap n' Proto message. As an optimization the return value message may have one or more of its segments pre-allocated on the stack. Some messages may not let you exceed the capacity of pre-allocated segments; if so, you must return DKSDK_FFI_ERR_INVALID_STATE.
- Param args:
[in] Cap n' Proto message whose root structure contains the arguments for the method. May be NULL.
- Return:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT on error
DKSDK_FFI_ERR_INVALID_STATE on error
DK_CLS_ERR_DEAD_OBJECT if there was a prior destructor call
any positive, non-zero number for a user error code
-
typedef int DK_INSTANCE_DESTRUCTOR(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic_instance *instance, const struct dksdk_ffi_c_cls_closure_data *closure, struct dk_cls_capnp_args *args)¶
A destructor on an instance.
Once a destructor is called, it is DkSDK FFI's responsibility to ensure no other destructor method will be called again for that instance. In other words, the destructor is idempotent and will not create a double free bug. When a second destructor is called (or the same destructor is called twice), DkSDK FFI will ignore the second destructor call.
Requirements¶
The instance method has a post-condition. It must release the
args
parameter with dksdk_ffi_c_cls_release_args, even if the method exited in error.The
args
parameter must not be released before the arguments have been parsed and used.
The timing of the dksdk_ffi_c_cls_release_args can be done whenever it is convenient. Choices include:
Releasing before the method exits
If the method queues up work in an event queue, releasing when the work is removed from the event queue
Why Destructor Arguments?¶
Although it is unusual for a programming language to have destructor arguments, DkSDK FFI's API mandates that arguments are passed to destructors. That is because method identifiers have a broad range and can map to destructors, instance methods or other types of methods. When you allocate method arguments something (the method, including destructor method) is responsible for de-allocating those arguments.
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param instance:
[in] The instance values of the instance object. Its
ptr
field has the pointer to the host object. The lifetime ofinstance
is only to the end of the instance method.- Param closure:
[in] Closure captured when the instance destructor was defined.
- Param args:
[in] Possibly null Cap n' Proto message whose root structure contains the arguments for the destructor method. May be NULL.
- Return:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT on error
DKSDK_FFI_ERR_INVALID_STATE on error
any positive, non-zero number for a user error code
-
typedef size_t DK_INSTANCE_HEAP_SIZE(const struct dksdk_ffi *ffi, const struct dksdk_ffi_c_cls_generic_instance *instance)¶
A function to over-estimate how much heap RAM is consumed by an instance object.
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param instance:
[in] The instance values of the instance object. Its
ptr
field has the pointer to the host object. The lifetime ofinstance
is only to the end of the heap size call.
-
typedef int METHOD_DISPATCH(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic *generic, struct dksdk_ffi_c_cls_generic_call_ctx *ctx, meth31 method31, struct dk_cls_capnp_args *args)¶
A function that routes to a specific method on an object.
The
args
parameter has move semantics. Ownership transfers to this function, even if there is an error. This function will, at some point, dksdk_ffi_release theargs
:If there is an error, the release is immediate
When the method is finished with the method arguments, the method must do the release
- Param ffi:
[in] The FFI pointer from dksdk_ffi_host_create
- Param generic:
[in] The generic class or instance object.
- Param ctx:
[in] Context for the call, including a message for a return value. The return value is an already initialized Cap n' Proto message. As an optimization the return value message may have one or more of its segments pre-allocated on the stack. Some messages may not let you exceed the capacity of pre-allocated segments; if so, you must return DKSDK_FFI_ERR_INVALID_STATE.
- Param method31:
[in] The 31-bit method identifier for the method name, obtained from dksdk_ffi_c_cls_generic_meth31.
- Param args:
[in] Reference-counted Cap n' Proto message whose root structure contains the arguments for the method.
- Return:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT on error
DKSDK_FFI_ERR_INVALID_STATE on error
DKSDK_FFI_ERR_NOT_FOUND when the method was not found
any positive, non-zero number for a user error code
-
typedef uint32_t iid31¶
The type for the hash of an interface identifier (IID).
Enums
-
enum dksdk_ffi_c_cls_generic_embedded_debug¶
Flags for whether debug information is embedded.
Values:
-
enumerator GENERIC_WITH_DEBUG¶
-
enumerator GENERIC_WITHOUT_DEBUG¶
-
enumerator GENERIC_WITH_DEBUG¶
-
enum dksdk_ffi_c_cls_generic_object_type¶
Whether the object is a class object or an instance object.
Values:
-
enumerator GENERIC_CLASS_OBJECT¶
-
enumerator GENERIC_INSTANCE_OBJECT¶
-
enumerator GENERIC_CLASS_OBJECT¶
-
enum dksdk_ffi_c_cls_generic_component_type¶
The type of component that will be added to a class.
Values:
-
enumerator component_class_end¶
-
enumerator component_class_method¶
-
enumerator component_class_destructor¶
-
enumerator component_instance_method¶
-
enumerator component_instance_destructor¶
-
enumerator component_abstract_instance_method¶
-
enumerator component_abstract_instance_destructor¶
-
enumerator component_intf¶
-
enumerator component_class_end¶
Functions
-
static inline struct dksdk_ffi_c_cls_self_data dksdk_ffi_c_cls_self_data_from_void_pointer(void *ptr)¶
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_call_ctx_initial(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic_call_ctx *ctxAddr)¶
Creates an initial context for one top-level (ie.
not nested) method call.
Typically you will want to allocate the
struct dksdk_ffi_c_cls_generic_call_ctx
as a local stack variable, and then call this function to initialize it. For example:struct dksdk_ffi_c_cls_generic_call_ctx ctx; ret = dksdk_ffi_c_cls_call_ctx_initial(ffi, &ctx); if (ret != DKSDK_FFI_OK) return; // do something with error
However, you can do heap allocation for
struct dksdk_ffi_c_cls_generic_call_ctx
; it then would be your responsibility for de-allocating the struct.After the call context is initialized:
you can set any of the flags like
host_configured_for_call_chain
orguest_configured_for_call_chain
It is your responsibility to call dksdk_ffi_c_cls_call_ctx_release_returnval after the call has been completed.
- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
ctxAddr -- [inout] The address of a
struct dksdk_ffi_c_cls_generic_call_ctx
that, on success, will be initialized to a call context and will have itsreturn_value
message reference count set to 1.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi, ctxAddr, or retValAddr are NULL
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_call_ctx_nest(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_call_ctx_params params)¶
Create a nested call context, where within a call context there is another call.
The typical usage is:
function callerScope() { struct dksdk_ffi_c_cls_generic_call_ctx callee_ctx; ret = dksdk_ffi_c_cls_call_ctx_nest( ffi, (struct dksdk_ffi_c_cls_call_ctx_params) { .callerPtr = &ctx, .calleeAddr = &callee_ctx}); if (ret != DKSDK_FFI_OK) return; // do something with error
// ... do call to the callee ...
dksdk_ffi_c_cls_call_ctx_release_returnval(ffi, &callee_ctx);
// .. do more calls to more callees ... }
It is your responsibility to call dksdk_ffi_c_cls_call_ctx_release_returnval on the callee (
calleeAddr
) after you have used the return value from a successful (DKSDK_FFI_OK) nested call.dksdk_ffi_c_cls_call_ctx_nest
will automatically release the return value if there is an error.- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
params -- [in] The parent and child context parameters
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi, or callerPtr or calleeAddr of params, are NULL
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_call_ctx_tail(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_call_ctx_params params)¶
Create a nested call context, where within a call context (the "caller") there a call (the "callee" call) in the tail position.
The typical usage is:
function callerScope(caller_ctx) { struct dksdk_ffi_c_cls_generic_call_ctx tailcall_ctx; ret = dksdk_ffi_c_cls_call_ctx_tail( ffi, (struct dksdk_ffi_c_cls_call_ctx_params) { .callerPtr = &ctx, .calleeAddr = &tailcall_ctx}); if (ret != DKSDK_FFI_OK) return; // do something with error
// do call to callee ... dksdk_ffi_release(ffi, &callee_args->com);
return; }
Unlike dksdk_ffi_c_cls_call_ctx_nest you should not use dksdk_ffi_c_cls_call_ctx_release_returnval on the callee (
calleeAddr
). Instead the callee's return value message is the caller's return value message, so it will be the responsibility of the caller to release the return value.- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
params -- [in] The parent and child context parameters
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi, or callerPtr or calleeAddr of params, are NULL
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_call_ctx_release_returnval(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic_call_ctx *ctxPtr)¶
Decrements the reference count of the call context's
return_value
message.Do not use the call context after this operation.
- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
ctxPtr -- [in] Pointer to the
struct dksdk_ffi_c_cls_generic_call_ctx
that, on success, will be initialized to a call context.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi or ctxPtr is NULL
DKSDK_FFI_ERR_INVALID_STATE when the context was corrupted, possibly due to double release.
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_release_args(struct dksdk_ffi *ffi, struct dk_cls_capnp_args *args)¶
Decrements the reference count of the method arguments.
Do not use the method arguments after this operation.
- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
args -- [in] Arguments to a method. May be NULL.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi or args is NULL
DKSDK_FFI_ERR_INVALID_STATE when the arguments were corrupted, possibly due to double release.
-
DKSDK_FFI_C_EXPORT dksdk_ffi_uuid dksdk_ffi_c_cls_generic_iid_of_qualname(const char *fullyQualifiedName)¶
Get the class identifier (CLSID) or interface identifier (IID) of the fully qualified class or interface name.
The returned UUID will be the least significant bytes of the SHA-256 hash of the concatenation of the fully qualified UTF-8 encoded name and a constant.
Use a CLSID with dksdk_ffi_registry_get(ffi, CLSID, &classObject) to retrieve a Generic class object.
The UTF-8 encoding may not contain a NUL code point (the code point 0).
- Parameters:
fullyQualifiedName -- [in] The name of the class or interface with
::
as the namespace separator, like in C++. An example could beStark::Accutech::BetaParticleGenerator
. The CLSID will be deterministically derived from this fully qualified class name.- Returns:
dksdk_ffi_uuid The CLSID for the class name or IID for the interface name.
-
DKSDK_FFI_C_EXPORT iid31 dksdk_ffi_c_cls_generic_iid31_of_qualname(const char *fullyQualifiedName)¶
Get the 31-bit variant of the class identifier (CLSID) or interface identifier (IID) of the fully qualified class or interface name.
The 31-bit variant is the least significant 32 bits of the SHA256 hash of the concatenation of the fully qualified UTF-8 encoded name and a constant, with the least significant bit set to one (1). The integer representation of the hash bits is little endian.
The 31-bit variant is used in hash tables, and can also be used:
as a normal C
uint32_t
after shifting to the right one bitas an unboxed OCaml signed integer, where the most significant bit is used as the sign bit in two's complement representation
as a v8 JavaScript small integer (Smi) after resetting the least significant bit to zero (0). See https://v8.dev/blog/pointer-compression
The UTF-8 encoding may not contain a NUL code point (the code point 0).
- Parameters:
fullyQualifiedName -- [in] The name of the class or interface with
::
as the namespace separator, like in C++. An example could beStark::Accutech::BetaParticleGenerator
. The CLSID will be deterministically derived from this fully qualified class name.- Returns:
uint32_t The 31-bit CLSID or IID expressed as an odd 32-bit number; the lowest bit will always be one (1).
-
DKSDK_FFI_C_EXPORT meth31 dksdk_ffi_c_cls_generic_meth31(const char *methodName)¶
Get the 31-bit method identifier.
Use the method identifier with (struct dksdk_ffi_c_cls_generic).method_dispatch to call a method.
The method identifier is the least significant 32 bits of the SHA256 of the concatenation of the UTF-8 encoded method name and a constant, with the least significant bit set to one (1).
The UTF-8 encoding may not contain a NUL code point (the code point 0).
See dksdk_ffi_c_cls_generic_iid31_of_qualname for how 31-bit numbers can be used.
- Parameters:
methodName -- [in] The UTF-8 encoded name of the method.
- Returns:
The method identifier
-
DKSDK_FFI_C_EXPORT int dk_add_class(struct dksdk_ffi *ffi, const char *fullyQualifiedClassName, DK_CLASS_DESTRUCTOR *classFallbackDtorMostlyRequired, struct dksdk_ffi_c_cls_closure_data classFallbackDtorClosure, DK_INSTANCE_HEAP_SIZE *heapSizeOverEstimator, DK_INSTANCE_DESTRUCTOR *instanceFallbackDtorMostlyRequired, struct dksdk_ffi_c_cls_closure_data instanceFallbackDtorClosure, ...)¶
Adds a class with all of its constructors, destructors, methods and interfaces.
The constructors, destructors and methods are supplied as individual parameters from builders of this header file, and must be terminated with DK_CLASS_END.
For example:
dk_add_class(ffi, "Posix::FILE::Readonly", &heap_size_over_estimator, &dtor, NO_CLOSURE, dk_abstract_instance_method("Read"), dk_abstract_instance_destructor("Close"), DK_CLASS_END); dk_add_class(ffi, "Posix::FILE", &heap_size_over_estimator, &dtor, NO_CLOSURE, dk_class_method("Open", &do_fopen, NO_CLOSURE), dk_class_method("OpenForRead", &do_fopen_readonly, NO_CLOSURE), dk_instance_method("Read", &do_fread, NO_CLOSURE), dk_instance_method("Write", &do_fwrite, NO_CLOSURE), dk_instance_destructor("Close", &do_fclose, NO_CLOSURE), dk_interface("Posix::FILE::Readonly"), DK_CLASS_END);
A Generic interface is a set of methods with no constructors and destructors. When
dk_add_class
succeeds, both a class will be created with the name fromfullyQualifiedClassName
(ex.Posix::FILE
) and a Generic interface will be created with the same name but with no constructors and destructors.Using dk_interface you can register sub-interfaces that the class supports. The sub-interfaces must have been already registered using
dk_add_class
containing only abstract methods.- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
fullyQualifiedClassName -- [in] The name of the class with
::
as the namespace separator, like in C++. An example could beStark::Accutech::BetaParticleGenerator
. The CLSID will be deterministically derived from this fully qualified class name.classFallbackDtorMostlyRequired -- [in] Required except when there are no class destructor
components
The fallback class destructor will be called when the number of references to any class object drops to zero, but no explicit class destructor has been called yet.classFallbackDtorClosure -- [in] The closure passed to
classFallbackDtorMostlyRequired
. Use NO_CLOSURE if there is noclassFallbackDtorMostlyRequired
.heapSizeOverEstimator -- [in] A function to calculate the heap size of the instance. If the function is an estimate, it should be an overestimate rather than an underestimate. If the instance takes no heap space, use zero_heap_size_estimator.
instanceFallbackDtorMostlyRequired -- [in] Required except when there are no instance destructor
components
The fallback instance destructor will be called when the number of references to any instance object drops to zero, but no explicit instance destructor has been called yet.instanceFallbackDtorClosure -- [in] The closure passed to
instanceFallbackDtorMostlyRequired
. Use NO_CLOSURE if there is noinstanceFallbackDtorMostlyRequired
.... -- Zero or more slots (constructors, destructors and/or methods) of type struct dksdk_ffi_c_cls_generic_component.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi or fullyQualifiedClassName is NULL.
DKSDK_FFI_ERR_INVALID_STATE when there is no more memory.
-
DKSDK_FFI_C_EXPORT int dk_xadd_class(struct dksdk_ffi *ffi, const char *fullyQualifiedClassName, DK_CLASS_DESTRUCTOR *classFallbackDtorMostlyRequired, struct dksdk_ffi_c_cls_closure_data classFallbackDtorClosure, DK_INSTANCE_HEAP_SIZE *heapSizeOverEstimator, DK_INSTANCE_DESTRUCTOR *instanceFallbackDtorMostlyRequired, struct dksdk_ffi_c_cls_closure_data instanceFallbackDtorClosure, size_t numComponents, const struct dksdk_ffi_c_cls_generic_component *components)¶
Non-variadic form of dk_add_class.
DK_CLASS_END must not be a component.
See also
dk_add_class
- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create
fullyQualifiedClassName -- [in] The name of the class with
::
as the namespace separator, like in C++. An example could beStark::Accutech::BetaParticleGenerator
. The CLSID will be deterministically derived from this fully qualified class name.classFallbackDtorMostlyRequired -- [in] Required except when there are no class destructor
components
The fallback class destructor will be called when the number of references to any class object drops to zero, but no explicit class destructor has been called yet.classFallbackDtorClosure -- [in] The closure passed to
classFallbackDtorMostlyRequired
. Use NO_CLOSURE if there is noclassFallbackDtorMostlyRequired
.heapSizeOverEstimator -- [in] A function to calculate the heap size of the instance. If the function is an estimate, it should be an overestimate rather than an underestimate. If the instance takes no heap space, use zero_heap_size_estimator.
instanceFallbackDtorMostlyRequired -- [in] Required except when there are no instance destructor
components
The fallback instance destructor will be called when the number of references to any instance object drops to zero, but no explicit instance destructor has been called yet.instanceFallbackDtorClosure -- [in] The closure passed to
instanceFallbackDtorMostlyRequired
. Use NO_CLOSURE if there is noinstanceFallbackDtorMostlyRequired
.numComponents -- [in] The number of components in the
components
parameterscomponents -- [in] Zero or more components (interfaces, constructors, destructors and/or methods) of type struct dksdk_ffi_c_cls_generic_component.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi or fullyQualifiedClassName is NULL.
DKSDK_FFI_ERR_INVALID_STATE when there is no more memory.
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_class_method(const char *name, DK_CLASS_METHOD *method, struct dksdk_ffi_c_cls_closure_data closure)¶
A class (also known as static) method.
- Parameters:
name -- The name of the static method.
method -- The method call.
closure -- [in] The closure that will be passed in all subsequent
method
invocations.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_class_destructor(const char *name, DK_CLASS_DESTRUCTOR *method, struct dksdk_ffi_c_cls_closure_data closure)¶
A class destructor.
Once a destructor is called, it is DkSDK FFI's responsibility to ensure no other destructor method will be called again for that class. In other words, the destructor is idempotent and will not create a double free bug. When a second destructor is called (or the same destructor is called twice), DkSDK FFI will ignore the second destructor call.
As a convenience to DkSDK FFI users, subsequent class methods may fail after a destructor has been called. However, because doing (atomic) checks for a prior destructor call on each class method call is expensive, release builds may have a relaxed memory consistency during the checks, or even optimize out the checks completely. It is the DkSDK FFI user's responsibility (you!) to not call more class methods after a destructor has been called.
- Parameters:
name -- The name of the destructor method.
method -- The method call.
closure -- [in] The closure that will be passed in all subsequent
method
invocations.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_instance_destructor(const char *name, DK_INSTANCE_DESTRUCTOR *method, struct dksdk_ffi_c_cls_closure_data closure)¶
An instance destructor.
Once a destructor is called, it is DkSDK FFI's responsibility to ensure no other destructor method will be called again for that instance. In other words, the destructor is idempotent and will not create a double free bug. When a second destructor is called (or the same destructor is called twice), DkSDK FFI will ignore the second destructor call.
As a convenience to DkSDK FFI users, subsequent instance methods may fail after a destructor has been called. However, because doing (atomic) checks for a prior destructor call on each instance method call is expensive, release builds may have a relaxed memory consistency during the checks, or even optimize out the checks completely. It is the DkSDK FFI user's responsibility (you!) to not call more instance methods after a destructor has been called.
- Parameters:
name -- The name of the instance destructor.
method -- The method call.
closure -- [in] The closure that will be passed in all subsequent
method
invocations.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_abstract_instance_destructor(const char *name)¶
An abstract instance destructor.
Once a destructor is called, it is DkSDK FFI's responsibility to ensure no other destructor method will be called again for that instance. In other words, the destructor is idempotent and will not create a double free bug. When a second destructor is called (or the same destructor is called twice), DkSDK FFI will ignore the second destructor call.
As a convenience to DkSDK FFI users, subsequent instance methods may fail after a destructor has been called. However, because doing (atomic) checks for a prior destructor call on each instance method call is expensive, release builds may have a relaxed memory consistency during the checks, or even optimize out the checks completely. It is the DkSDK FFI user's responsibility (you!) to not call more instance methods after a destructor has been called.
- Parameters:
name -- The name of the instance destructor.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_instance_method(const char *name, DK_INSTANCE_METHOD *method, struct dksdk_ffi_c_cls_closure_data closure)¶
An instance method.
- Parameters:
name -- The name of the instance method.
method -- The method call.
closure -- [in] The closure that will be passed in all subsequent
method
invocations.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_abstract_instance_method(const char *name)¶
An abstract instance method.
- Parameters:
name -- The name of the abstract instance method.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component dk_interface(const char *name)¶
Add one of a maximum 63 interfaces that the class supports.
The interface name must have already been registered with a previous dk_add_class(ffi, INTERFACE_NAME), typically with all the methods as abstract methods.
- Parameters:
name -- The fully qualified interface name.
- Returns:
The struct dksdk_ffi_c_cls_generic_component you use in dk_add_class
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_generic_new_instance(struct dksdk_ffi *ffi, struct dksdk_ffi_c_cls_generic_class_fields *ctor, const struct dksdk_ffi_c_cls_self_data self_data, dksdk_ffi_uuid *oid)¶
Create a new instance of a generic class from a given host object pointer.
Consider using dksdk_ffi_c_cls_generic_ref_to_new_object if you are implementing a DK_CLASS_METHOD class method.
- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create.
ctor -- [in] A constructor value.
self_data -- [in] The representation of the
self
orthis
host object. May be zeroed for singleton or static host objects.oid -- [out] Pointer to a UUID which will be populated with the new instance's object ID on success.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi, genericClass or oid is NULL
DKSDK_FFI_ERR_INVALID_STATE when there is no memory to create a new instance, or the class constructor failed
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_generic_ref_to_new_object(struct dksdk_ffi *ffi, const dksdk_ffi_uuid *iid, struct dksdk_ffi_c_cls_generic_class_fields *ctor, struct dksdk_ffi_c_cls_generic_call_ctx *ctx, const struct dksdk_ffi_c_cls_self_data self_data)¶
Convenience function to create an object, and then return an object reference to that object.
Typically used as the last statement in an implementation of a DK_CLASS_METHOD class method.
An object reference is a
:Data
blob with the first 128-bits as the object id, and the last 128-bits as the interface id. The return value will be populated with the object reference if successful.- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create.
iid -- [in] The pointer to the interface identifier (IID) that should be used when interacting with the object.
ctor -- [in] A constructor value, typically available as a parameter to a DK_CLASS_METHOD class method.
ctx -- [in] Context for the call.
self_data -- [in] The representation of the
self
orthis
host object. May be zeroed for singleton or static host objects.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi, iid, ctor, or retval is NULL
DKSDK_FFI_ERR_INVALID_STATE when there is no memory to create a new instance, or the class constructor failed
-
DKSDK_FFI_C_EXPORT int dksdk_ffi_c_cls_generic_delete_com_object(struct dksdk_ffi *ffi, struct ComObject com_object)¶
Deletes the specified COM object from the registry.
Typically used when inspecting the GenericReturn from a COM method call, and seeing a COM object reference when only a value was expected. You would need to delete the COM object reference and then return an error to your caller.
- Parameters:
ffi -- [in] The FFI pointer from dksdk_ffi_host_create.
com_object -- [in] The 2 x 128-bit binary object reference to the COM object. The
com_object
Cap n' Proto structure's data pointer will be resolved with capn_resolve before it is read.
- Returns:
DKSDK_FFI_OK on success
DKSDK_FFI_ERR_INVALID_ARGUMENT when ffi is NULL or the com_f is not a valid COM object reference
DKSDK_FFI_ERR_NOT_FOUND when the object can't be found
-
static inline size_t zero_heap_size_estimator(const struct dksdk_ffi *ffi, const struct dksdk_ffi_c_cls_generic_instance *instance)¶
A heap size estimator that always returns zero.
Use when there is no heap space taken by an instance.
Variables
-
DKSDK_FFI_C_EXPORT const dksdk_ffi_uuid DK_IID_GENERIC_CLASS¶
The interface identifier for the class object
dksdk_ffi_c_cls_generic
.
-
DKSDK_FFI_C_EXPORT const struct dksdk_ffi_c_cls_closure_data NO_CLOSURE¶
A zeroed closure.
-
DKSDK_FFI_C_EXPORT struct dksdk_ffi_c_cls_generic_component DK_CLASS_END¶
The required end to the varargs list of components passed into dk_add_class.
-
struct capn_args_ret¶
- #include <cls_generic.h>
Arguments and return value for a method call using Cap n' Proto messages.
Public Members
-
struct dk_cls_capnp_args *args¶
Arguments for a method call.
-
struct dk_cls_capnp_retval *retval¶
Return value from a method call.
-
struct dk_cls_capnp_args *args¶
-
struct dksdk_ffi_c_cls_closure_data¶
- #include <cls_generic.h>
An opaque piece of data that captures the environment values that a method or destructor was defined in.
The closure data will be passed into the method or destructor on each method invocation or destructor call.
Public Members
-
char data[DK_CLS_MAX_FAT_POINTER_SZ]¶
A 256-bit opaque data blob that passed into an class/instance method or destructor.
The data is unique to the DkSDK FFI platform. For example, C does not have closures so this data will typically be zero (NO_CLOSURE) in C. Other platforms may use a pointer to their language's real closure, or "fat pointers" that are pointers annotated with extra data.
-
char data[DK_CLS_MAX_FAT_POINTER_SZ]¶
-
struct dksdk_ffi_c_cls_self_data¶
- #include <cls_generic.h>
A representation of a
self
orthis
that will be passed into an instance method or instance destructor.Public Members
-
char data[DK_CLS_MAX_FAT_POINTER_SZ]¶
The
self
orthis
as a fat pointer.
-
void *ptr¶
The
self
orthis
as a regular pointer.Do not set directly. Instead use dksdk_ffi_c_cls_self_data_from_void_pointer so that the other bits are set to zero.
-
union dksdk_ffi_c_cls_self_data self¶
A pointer to the host object that FFI platforms pass as
self
orthis
into an instance method or instance destructor.You have a choice of representing your host object pointer as a
void *
(ie. 64-bits on a 64-bit system) or a 256-bit opaque data. The 256-bit opaque data blob is the right choice on platforms that use "fat pointers" which are pointers annotated with extra data.
-
char data[DK_CLS_MAX_FAT_POINTER_SZ]¶
-
struct dksdk_ffi_c_cls_generic_call_ctx¶
- #include <cls_generic.h>
The context of a call to a generic object.
Public Members
-
DK_MESSAGE_BUILDER *builder¶
Create a message that can be used to build a return value message from a method call, or an arguments message to a method call.
-
struct dk_cls_capnp_retval *return_value¶
The reference-counted return value message.
-
int host_configured_for_call_chain¶
Non-zero if and only if the host platform has been known to be configured for the call chain.
Being "configured" is platform specific, but generally includes setting up platform locks (if any) and/or platform thread local variables.
-
int guest_configured_for_call_chain¶
Non-zero if and only if the guest platform has been known to be configured for the call chain.
Being "configured" is platform specific, but generally includes setting up platform locks (if any) and/or platform thread local variables.
-
DK_MESSAGE_BUILDER *builder¶
-
struct dksdk_ffi_c_cls_generic_instance¶
- #include <cls_generic.h>
Values available to instance methods.
Public Members
-
struct dksdk_ffi_c_cls_self_data self_data¶
A representation of the host object that FFI platforms pass as
self
orthis
into an instance method or instance destructor.
-
struct dksdk_ffi_i_com *com¶
The COM object.
The COM object is useful to do
dksdk_ffi_release(ffi, &instance->com)
when an instance terminates itself.
-
struct dksdk_ffi_c_cls_self_data self_data¶
-
struct dksdk_ffi_c_cls_generic_vtable¶
- #include <cls_generic.h>
Virtual methods for the Generic class.
Public Members
-
dksdk_ffi_i_com_vtable com_vtable¶
The C++ style virtual table containing the Generic methods.
-
METHOD_DISPATCH *method_dispatch¶
The method dispatcher.
See METHOD_DISPATCH.
-
dksdk_ffi_i_com_vtable com_vtable¶
-
struct dksdk_ffi_c_cls_generic_instance_interface_fields¶
- #include <cls_generic.h>
Values for an instance object, specific to a single one of its supported interfaces.
Public Members
-
dksdk_ffi_uuid interface_iid¶
One of the instance object's supported interfaces.
-
int is_concrete¶
Concrete (non-zero) means all interface methods are available as instance (not abstract) methods in the instance object.
-
struct dksdk_ffi_c_cls_generic_s128_set *method_names_opt¶
The names of the abstract and instance methods belonging to the supported interface.
NULL is valid if there are no methods.
-
struct dksdk_ffi_c_cls_generic_u32_set *abstract_instance_meth31_ids_opt¶
The abstract instance methods allowed by this interface.
The key is the meth31 method identifier.
-
struct dksdk_ffi_c_cls_generic_u32_set *abstract_instance_dtor31_ids_opt¶
The abstract destructor methods allowed by this interface.
The key is the meth31 method identifier.
-
struct dksdk_ffi_c_cls_generic_u32_set *instance_meth31_ids_opt¶
The instance methods allowed by this interface.
The key is the meth31 method identifier.
-
struct dksdk_ffi_c_cls_generic_u32_set *instance_dtor31_ids_opt¶
The destructors allowed by this interface.
The key is the meth31 method identifier.
-
enum dksdk_ffi_c_cls_generic_embedded_debug embedded_debug¶
Controls whether debug information embedded into the structure.
-
char truncated_interface_name[128]¶
-
dksdk_ffi_uuid interface_iid¶
-
struct dksdk_ffi_c_cls_generic_instance_fields¶
- #include <cls_generic.h>
Values for an instance object.
Public Members
-
char self_data[DK_CLS_MAX_FAT_POINTER_SZ]¶
Pointer to the host object.
The pointer may be a "fat pointer" which is a regular pointer annotated with extra data.
-
DK_INSTANCE_DESTRUCTOR *fallback_instance_dtor2¶
Fallback destructor.
Required when there are explicit instance destructor methods. This destructor will be called for any instance which has had no explicit instance destructor call.
-
struct dksdk_ffi_c_cls_closure_data fallback_instance_dtor_closure2¶
Closure data for
fallback_instance_dtor
.
-
char self_data[DK_CLS_MAX_FAT_POINTER_SZ]¶
-
struct dksdk_ffi_c_cls_generic_slot¶
- #include <cls_generic.h>
Values common to a slot (a constructor or a destructor or a method).
Public Members
-
DK_CLASS_METHOD *class_method¶
-
DK_CLASS_DESTRUCTOR *class_destructor¶
-
DK_INSTANCE_METHOD *instance_method¶
-
DK_INSTANCE_DESTRUCTOR *instance_destructor¶
-
union dksdk_ffi_c_cls_generic_slot slot¶
-
struct dksdk_ffi_c_cls_closure_data closure¶
-
int is_destructor¶
-
DK_CLASS_METHOD *class_method¶
-
struct dksdk_ffi_c_cls_generic_class_fields¶
- #include <cls_generic.h>
Values for a class object.
Public Members
-
dksdk_ffi_uuid clsid¶
CLSID.
-
int is_abstract¶
Abstract (non-zero) means that a new object can't be instantiated.
-
DK_CLASS_DESTRUCTOR *class_fallback_dtor_opt2¶
Fallback destructor.
Required when there are explicit class destructor methods. This destructor will be called for any class which has had no explicit class destructor call.
-
struct dksdk_ffi_c_cls_closure_data class_fallback_dtor_closure2¶
Closure data for
class_fallback_dtor_opt
.
-
DK_INSTANCE_HEAP_SIZE *new_instance_heap_size_over_estimator¶
The heap size, or an over-estimate of, instances.
-
size_t new_instance_num_slots¶
The number of slots new instance objects will support.
-
struct dksdk_ffi_c_cls_generic_slot *new_instance_slots¶
Array of instance functions.
The array is of length new_instance_num_slots
-
size_t new_instance_num_intfs¶
The number of interfaces new instance objects will support.
-
struct dksdk_ffi_c_cls_generic_instance_interface_fields *new_instance_interface_fields¶
Array of fields that will populate each interface of a new instance.
The array is of length new_instance_num_intfs
-
DK_INSTANCE_DESTRUCTOR *new_instance_fallback_dtor_opt2¶
Optional fallback destructor.
If specified, then this destructor will be called for any instance which has had no explicit destructor call.
-
struct dksdk_ffi_c_cls_closure_data new_instance_fallback_dtor_closure2¶
Closure passed to
new_instance_fallback_dtor_opt
.
-
struct dksdk_ffi_c_cls_generic_u32_u32_table *new_instance_method_dispatch_table¶
The method dispatch table for new instance objects.
-
dksdk_ffi_uuid clsid¶
-
struct dksdk_ffi_c_cls_generic¶
- #include <cls_generic.h>
Generic is an object managed by the host language (C).
Its methods are dksdk_ffi_c_cls_generic_vtable.
Public Members
-
struct dksdk_ffi_i_com com¶
The always-valid DkSDK FFI COM superclass.
Use this superclass to access private fields of the DkSDK FFI COM superclass.
-
dksdk_ffi_c_cls_generic_vtable *vtable_generic¶
The always-valid virtual table for the Generic class.
Use this virtual table to access virtual methods.
- union dksdk_ffi_c_cls_generic
The DkSDK FFI COM object superclass, with the virtual method table extended to conform to dksdk_ffi_c_cls_generic_vtable.
-
enum dksdk_ffi_c_cls_generic_object_type object_type¶
The type of generic_fields.
-
struct dksdk_ffi_c_cls_generic_u32_set *instance_dtor31_ids_opt¶
The instance destructors that are part of this interface.
The key is the meth31 method identifier.
Ignored and expected to be NULL if this is a class object.
-
struct dksdk_ffi_c_cls_generic_u32_set *instance_meth31_ids_opt¶
The instance methods that are part of this interface.
The key is the meth31 method identifier.
Ignored and expected to be NULL if this is a class object.
-
DK_INSTANCE_HEAP_SIZE *instance_heap_size_over_estimator¶
The heap size, or an over-estimate of, the instance object.
Ignored and expected to be NULL if this is a class object.
-
union dksdk_ffi_c_cls_generic::u_generic_fields generic_fields¶
-
enum dksdk_ffi_c_cls_generic_embedded_debug embedded_debug¶
Controls whether debug information embedded into the structure.
-
char truncated_interface_name[128]¶
-
union u_generic_fields¶
- #include <cls_generic.h>
Either the class fields or the instance fields.
Public Members
-
struct dksdk_ffi_c_cls_generic_class_fields *class_fields_ptr¶
The class fields are pointers so there is only one source of truth.
Makes dealing with race conditions easier (only need to deal with thread synchronization).
-
struct dksdk_ffi_c_cls_generic_instance_fields *instance_fields_ptr¶
The instance fields are pointers so there is only one source of truth.
Makes dealing with race conditions easier (only need to deal with thread synchronization).
-
struct dksdk_ffi_c_cls_generic_class_fields *class_fields_ptr¶
-
struct dksdk_ffi_i_com com¶
-
struct dksdk_ffi_c_cls_call_ctx_params¶
- #include <cls_generic.h>
Parameters to dksdk_ffi_c_cls_call_ctx_nest.
Public Members
-
struct dksdk_ffi_c_cls_generic_call_ctx *callerPtr¶
The parent context.
-
struct dksdk_ffi_c_cls_generic_call_ctx *calleeAddr¶
The address of the will-be-initialized child
struct dksdk_ffi_c_cls_generic_call_ctx
.On success, it will be initialized and will have its
return_value
message reference count set to 1.
-
struct dksdk_ffi_c_cls_generic_call_ctx *callerPtr¶
-
struct dksdk_ffi_c_cls_generic_component¶
- #include <cls_generic.h>
A component - the basic building block for a class - that is supplied to dk_add_class.
You do not create this structure directly. Instead use one of the following:
dk_abstract_instance_method
dk_abstract_instance_destructor
dk_class_method
dk_class_destructor
dk_instance_method
dk_instance_destructor
dk_interface
Public Members
-
enum dksdk_ffi_c_cls_generic_component_type component_type¶
-
char component_name[128]¶
-
char closure_data[DK_CLS_MAX_FAT_POINTER_SZ]¶
-
dksdk_ffi_uuid generic_interface_clsid¶
-
DK_CLASS_METHOD *class_method¶
-
DK_CLASS_DESTRUCTOR *class_destructor¶
-
DK_INSTANCE_METHOD *instance_method¶
-
DK_INSTANCE_DESTRUCTOR *instance_destructor¶