Mapping
To be able to follow the OSGi specification, a standard mapping from C to Java is defined. This mapping takes care of how instances, parameters, return values and error codes are used.
Example
Before going into detail, here is an example of the mapping from a method in Java to a function in C:
celix_status_t bundleContext_getServiceReferences(BUNDLE_CONTEXT context, const char * serviceName, char * filter, ARRAY_LIST *service_references) :::java public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException
Template
Using the provided example, the following template can be extracted:
/** * celix_status_t: return type of the status code * * typeName: name of the object/type this function is part of * functionName: the name of the function * * typeName_t: The actual instance to "invoke" this function on * pool: optional pool on which the output is allocated * parameters: default function parameters * output parameters: the output which the caller can use */ celix_status_t typeName_functionName([typeName_t instance, ][apr_pool_t *pool, ][parameters, ][output parameters]);
Details
To fully explain the mapping, the following items will be detailed:
- Instance parameter
- Error codes
- Output parameters
- Memory pools
Instances
When using Java, methods are related to an instance of a type. So for example, when the "getServiceReferences" method is used, it is always executed on an instance of BundleContext. When using C, functions are not related to any type, and as such, no instance information is available. To make this possible in Celix a pointer to the needed instance is always passed as first argument. The only exception are the "create" functions, they are used to create a new instance.
Furthermore, the instance typename is used as part of the function name, see "design.html" for more information.
Error codes
The OSGi specification uses Java Exceptions for error handling. Even though there are Exceptions-like solutions for C, Celix uses the simpler approach. Every method in Celix returns an status code (celix_status_t), this code can be used for error handling.
Output parameters
Since the return value is always used for the status code output parameters are used to get a possible result from a function. Celix uses pass-by-reference for this, the uses has to supply a pointer to the function to get the results. Using this mechanism it is also possible to use multiple output parameters. Celix always uses the last parameter(s) for output, and the caller has to NULL-initialize the result field.
Memory pools
Celix uses APR memory pools for allocation. In the case a functions result has to be allocated to the caller its own pool, the pool has to be supplied as an parameter. Note: Not all of Celix' API have been updated to use APR (and memory pools), this is a work in progress.
