The library export two functions (upf_init_ and upf_done) and variable upf_middleware which is a pointer upf_middlewareLayer structure. This structure contains pointers to various functions, number of ABI version (so that incompatible plugins are not loaded by mistake) and pointer to upf::IManager and upf::IServiceManager instances.
All instances are represented with upf_Object structure, which contains four members:
upf_InterfaceData contains opaque data pointer (this is typically not same as upf_Object's data pointer and it has different values for same upf_Object but different interfaces!) and dispatch function.
Dispatch function is called when a method call is being made. It takes 3 arguments: the data pointer, method ID and arguments. Method ID is method's number (starting from 0, in the order the methods appear in IDL, methods inherited from superinterface first). Arguments are stored in upf_Arguments using marchaller_write from upf_middleware. Basic types are stored as native types defined as C mapping of IDL types by CORBA (e.g. uint32_t for unsigned long), custom types may be serialized as the app wishes, interface pointers are serialized as void*.
Dispatch function is implemented in language-dependent manner, but it will usually contain a table of method pointers.
Language specific generated headers (or other files) then contains proxy classes and dispatcher function to translate native calls into ABI dispatches.
1.3.9.1