Since many FFI languages can participate in a single process, we need a convention for the many binary artifacts produced by the FFI languages to be linked into the process' executable.

One FFI language is assigned as the "host" language. The host language is responsible for executing dksdk_ffi_host_create(). If more than one FFI language executes dksdk_ffi_host_create() than the second and subsequent executions should fail but may not if there are race conditions. So the recommendation is for all FFI languages to use dksdk_ffi_host_get_or_create() which safely picks a single "host" language winner even in the presence of threads.

The convention is for each FFI language to produce a static library containing code specific to that FFI language. There should be one "fat" FFI language static library that contains a full copy of the DkSDK FFI C library; the DkSDK FFI C library itself trivially satisfies the requirements for that fat FFI language. It is a convention that the fat library is from the FFI language that will be the first host language winner; however, the fat library's language and the host language do not have to match.

Once you have one fat FFI language static library and zero or more non-fat FFI language static libraries, you can bundle all of those static libraries into a single shared library.

Here is a fully-worked example where DkSDK FFI Java produces the fat static library. If there is a "Source Library", the symbol has been re-exported from that library.

Static Library

Symbols Defined

Source Library


extern dksdk_ffi_host_create



extern dksdk_ffi_c_logger_log



extern dksdk_ffi_ocaml_register


Notice that the functions are simple extern functions without any __declspec(dllexport). It is possible to separate each FFI language library into separate shared libraries, but that is not the recommended convention.