lib Legato
The Legato Application Framework provide a set of APIs to simplify common C programming tasks. lib
Legato
adds object oriented functions to simplify and enhance the safety and reliability of your systems.
These APIs are available automatically to your applications by including legato.h
into your code.
It is also good practice to include interfaces.h
. interfaces.h
is a C header file that automatically includes all client and server interface definition that your client imports and exports. If you need to import or export any other API you will need to explicitly include interfaces.h
into your C or C++ code.
#include "legato.h" #include "interfaces.h"
API Guide | API Reference | File Name | Description |
---|---|---|---|
Command Line Arguments API | le_args.h | le_args.h | Provides the ability to add arguments from the command line |
Atomic File Operation API | le_atomFile.h | le_atomFile.h | Provides atomic file access mechanism that can be used to perform file operation (specially file write) in atomic fashion |
Basic Type and Constant Definitions | le_basics.h | le_basics.h | Provides error codes, portable integer types, and helpful macros that make things easier to use |
System Clock API | le_clock.h | le_clock.h | Gets/sets date and/or time values, and performs conversions between these values. |
CRC32 API | le_crc.h | le_crc.h | Provides the ability to compute the CRC of a binary buffer |
Directory API | le_dir.h | le_dir.h | Provides functions to control directories |
Doubly Linked List API | le_doublyLinkedList.h | le_doublyLinkedList.h | Provides a data structure that consists of data elements with links to the next node and previous nodes |
Event Loop API | le_eventLoop.h | le_eventLoop.h | Provides event loop functions to support the event-driven programming model |
File Descriptor Monitor API | le_fdMonitor.h | le_fdMonitor.h | Provides monitoring of file descriptors, reporting, and related events |
File Locking API | le_fileLock.h | le_fileLock.h | Provides file locking, a form of IPC used to synchronize multiple processes' access to common files |
File System service | le_fs.h | le_fs.h | Provides a way to access the file system across different platforms |
HashMap API | le_hashmap.h | le_hashmap.h | Provides creating, iterating and tracing functions for a hashmap |
Hex string API | le_hex.h | le_hex.h | Provides conversion between Hex and Binary strings |
JSON Parsing API | le_json.h | le_json.h | Provides fast parsing of a JSON data stream with very little memory required |
Logging API | le_log.h | le_log.h | Provides a toolkit allowing code to be instrumented with error, warning, informational, and debugging messages |
Dynamic Memory Allocation API | le_mem.h | le_mem.h | Provides functions to create, allocate and release data from a memory pool |
Low-level Messaging API | le_messaging.h | le_messaging.h | Provides support to low level messaging within Legato |
Mutex API | le_mutex.h | le_mutex.h | Provides standard mutex functionality with added diagnostics capabilities |
Low-level Pack/Unpack API | le_pack.h | le_pack.h | Provides low-level pack/unpack functions to support the higher level IPC messaging system |
Path API | le_path.h | le_path.h | Provides support for UTF-8 null-terminated strings and multi-character separators |
Path Iterator API | le_pathIter.h | le_pathIter.h | Iterate over paths, traverse the path node-by-node, or create and combine paths together |
Random Number API | le_rand.h | le_rand.h | Used for cryptographic purposes such as encryption keys, initialization vectors, etc. |
Safe References API | le_safeRef.h | le_safeRef.h | Protect from damaged or stale references being used by clients |
Semaphore API | le_semaphore.h | le_semaphore.h | Provides standard semaphore functionality, but with added diagnostic capabilities |
Signals API | le_signals.h | le_signals.h | Provides software interrupts for running processes or threads |
Singly Linked List API | le_singlyLinkedList.h | le_singlyLinkedList.h | Provides a data structure consisting of a group of nodes linked together linearly |
Unit Testing API | le_test.h | le_test.h | Provides macros that are used to simplify unit testing |
Thread Control API | le_thread.h | le_thread.h | Provides controls for creating, ending and joining threads |
Timer API | le_timer.h | le_timer.h | Provides functions for managing and using timers |
tty API | le_tty.h | le_tty.h | Provides routines to configure serial ports |
UTF-8 String Handling API | le_utf8.h | le_utf8.h | Provides safe and easy to use string handling functions for null-terminated strings with UTF-8 encoding |
Overview
Here is some background info on Legato's C Language APIs.
Object-Oriented Design
The Legato framework is constructed in an object-oriented manner.
The C programming language was created before object-oriented programming was popular so it doesn't have native support for OOP features like inheritance, private object members, member functions, and overloading. But object-oriented designs can still be implemented in C.
In the Legato C APIs, classes are hidden behind opaque "reference" data types. You can get references to objects created behind the scenes in Legato, but you can never see the structure of those objects. The implementation is hidden from view. Access to object properties is made available through accessor functions.
Opaque Types
The basic "opaque data type" offered by the C programming language is the "void pointer" (void *)
. The idea is that a pointer to an object of type T can be cast to point to a void
type before being passed outside of the module that implements T.
This makes it impossible for anyone outside of the module that implements T to dereference the pointer or access anything about the implementation of T. This way, the module that implements T is free to change the implementation of T in any way needed without worrying about breaking code outside of that module.
The problem with the void pointer type is that it throws away type information. At compile time, this makes it impossible to detect that a variable with opaque type T has been passed into a function with some other pointer type P.
To overcome this, Legato uses "incomplete types" to implement its opaque types. For example, there are declarations similar to the following in Legato C API header files:
// Declare a reference type for referring to Foo objects.typedef struct le_foo* le_foo_Ref_t;
But "struct le_foo" would not be defined in the API header or anywhere outside of the hypothetical "Foo" API's implementation files. This makes "struct le_foo" an "incomplete type" for all code outside of the Foo API implementation files. Incomplete types can't be used because the compiler doesn't have enough information about them to generate any code that uses them. But pointers to incomplete types can be passed around because the compiler always knows the pointer size. The compiler knows that one incomplete type is not necessarily interchangeable with another, and it won't allow a pointer to an incomplete type to be used where a pointer to another non-void type is expected.
Handlers and Event-Driven Programs
"Handler" is an alias for "callback function". Many APIs in the Legato world use callback functions to notify their clients of asynchronous events. For example, to register a function called "SigTermHandler" for notification of receipt of a TERM signal,
le_sig_SetEventHandler(SIGTERM, SigTermHandler);
Instead of using "CallbackFunction", "CallbackFunc", or some abbreviation like "CbFn" (Cub fun? Cubs fan? What?) that is difficult to read and/or remember, "Handler" is used.
The term "handler" also fits with the event-driven programming style that is favoured in the Legato world. These callback functions are essentially event handler functions. That is, the function is called when an event occurs to "handle" that event.
Copyright (C) Sierra Wireless Inc.