Component.cdef
files can contain these sections:
sources
import
export
files
requires
Contains a list of source code files.
One source file must implement a COMPONENT_INIT
function called at start-up.
Lists IPC API definitions required by this component from other components.
Each entry in the import list must have an interface definition (.api) file.
Optionally, it may also contain an interface name followed by an equals sign ('=') in front of the .api file path. If the interface name is omitted, the name of the
.api file (minus the ".api" extension) will be used as the name of the interface. All symbols (type names and function names) defined in the
.api file will be prefixed with this interface name and an underscore.
The build tools search for the interface definition (.api) file based on the interface search path.
Inside the component’s source code, you can call API functions defined inside the .api files. The types and functions defined in the
.api file will appear inside the component with the interface name (plus an underscore) prepended to them.
For example, if the greet.api
file contains a function called Greet()
, it will appear inside the component as hello_Greet()
. And the StartReadTxn()
function declared in le_cfg.api
will appear to the component as le_cfg_StartReadTxn()
.
In C/C++, source code must #include “interfaces.h” to use the auto-generated function definitions.
Multiple instances of the same API listed in the “import” section must have unique instance names, and will appear as separate functions with different prefixes.
If digitalOutput.api
defines two functions On()
and
Off(), then the component’s source code would have four functions available to it: heat_On()
, heat_Off()
, cool_On()
, and cool_Off()
.
Normally, when an API is imported by a component, the component will want to use that API (i.e., call its functions), so the build tools will automatically generate the client-side IPC code for that API and automatically try to connect to the server when the executable is run. There are a couple of options that can be used to suppress this behaviour.
The [types-only] option tells the build tools the client only wants to use type definitions from the API. When this option is present, the client-side IPC code will not be generated for this API, but the types defined in the API will still be made available to the component (through
interfaces.h
in C/C++.)
The [manual-start] option tells the build tools not to automatically connect to this API's server when the process starts. If this option is used, the component can control exactly when it wants to connect to the server by calling the
xxxx_ConnectService()
function explicitly in the component source code.
Lists IPC services provided by this component to other components. Contents use essentially the same syntax as the the import section, except the options are different.
The component code must implement the functions defined inside the .api files.
The function and data type names defined in the .api files must be prefixed with the interface name and an underscore.
If greet.api
defines a function called Greet()
, the source code for the component must implement a function called hello_Greet()
.
In C, the source code must #include “interfaces.h” to get the function prototype definitions.
The [manual-start] option tells the build tools not to automatically advertise this API with the Service Directory when the process starts. If this option is used, the component can control exactly when it wants to start offering the service to others by calling the
xxxx_AdvertiseService()
function explicitly in the component source code when it is ready.
Often, the server of a service can simply implement the functions as if they were called directly by the client (even though the client may be running inside another process). So, when the client calls an API function, the server's API function gets called, and when the server returns from the function, the function returns in the client process.
However, sometimes the server needs to hold onto the client request and do other things (perhaps handing requests from other clients) before sending a response back to the client and allowing the client to continue. This is called "asynchronous" mode, and it is enabled using the [async]
keyword on the end of the export
section entry.
When asynchronous mode is enabled for an interface, the server-side generated code changes as follows:
commandRef
parameter is added to the beginning of all the API functions' parameter lists.Respond()
function is generated for every API function.In async mode, the server responds to the client's call to API function F()
by calling the associated FRespond()
function.
The Respond
functions all take the commandRef
as their first parameter. If an API function has a return value, that return value is sent to the client via the second parameter of the Respond
function.
The same as the files section in .adef files.
The requires:
section is used to specify things that the component needs from its runtime environment.
Eventually, this will support "file:", "dir:", "lib:", and "api:" subsections, but for now, only "lib:" subsections are supported.
The lib:
subsection of the requires:
section is used to add a required library to a Component.
A required library is a library file that is expected to exist in the target file system (outside the application's sandbox) that the component needs access to at runtime.
Furthermore, this library will be linked with any executable that this component is a part of. The library name is specified without the leading "lib" or the trailing ".so".
requires: lib: foo // I need access to libfoo.so
Copyright (C) Sierra Wireless, Inc. 2014. All rights reserved. Use of this work is subject to license.