![]() |
ooc
1.3c
Object Oriented tollkit fo ANSI C
|
The ooc was designed to be easily portable.
Creating ooc the main goal was to establish an OOP environment that is easily portable onto special systems as well, like small microcumputers, microcontrollers and DSPs that has at least an ANSI compatible C compiler.
All portability issues are collected into separated header files, that I call porting headers. Each port has its own porting header in the directory named libs/port in the source tree, and include/ooc/port in the installed system.
In the main header file (ooc.h
) there is an include tree, that decides which porting header should be included.
Currently the following porting headers are available:
Porting header | Description |
anyc.h | Uses ANSI-C only, should be able to be compiled by any C compiler. There is no multithreading support in this port! |
gnuc.h | Linux 32 bit x86 port with GNU GCC compilation. Pthread or OpenMP multithreading is supported as well as single threading. |
msvc.h | Microsoft Windows 32 bit x86 port with MS Visual C++ compilation. Windows threads and OpenMP multithreading is supported as well as single threading. |
mcc18.h | MPLAB C18 compiler support for 8 bit Microchip controllers. There is no dynamic memory allocation and multithreading support in this port. Supports the large data + large code configuration only. |
mcc30.h | MPLAB C30 compiler support for 16 bit Microchip controllers. There is no multithreading support in this port. |
mcc32.h | MPLAB C32 compiler support for 32 bit Microchip controllers. There is no multithreading support in this port. |
For special comments on the existing ports see the following descriptions:
To create a new port you must do the followings:
When you create a new porting header it is advisable to start out from the closest existing header, worst case from anyc.h
. Copy it into the libs/port directory with a new name.
The porting header must contain the followings parts:
Include the necessary standard libraries in your system. See standard includes for details.
Longjump primitives are used for exception handling. You must define how your system handles longjumps, or you must implement a longjump mechanism on your own.
If your compiler allows, you can set some functions inline for better performance. To achive this define the STIN
macro as the prefix for static inline functions, and undefine NO_INLINE macro.
If your compiler does not support function inlining, leave this section as follows.
You must define the threading primitives for the given port.
Define the appropriate prefix for thread local storage variables, or leave the TLS
macro as follows:
Define the mutex and locking primitives for the current system. For a threadless implementation this looks like:
Define an atomic pointer exchange (read while nulling) operation as a macro called OOC_IMPLEMENT_PTR_READ_AND_NULL
. This is very important for threadsafe pointer manipulation. It is used for nulling a pointer while reading its content into a temporary variable.
If your implementation is threadless, this operatin must be reentrance safe. The reentrance safe default implementation is the following:
COMPILING_OOC_C
macro ensures, that this definition is available in the ooc core implementation only.You can use several macros that alter the behavior of the code according to the actual needs of your port.
Macro name | Behavior |
ROM | In case of a microcontroller, the const data could be located in Read Only Memory.For those targets define ROM macro as the appropriate storage specifier.ROM is used when dereferencing a ROM based variable. For allocation purposes see the ROM_ALLOC macro! If not specified it is defined automatically as:#define ROM const
|
ROM_ALLOC | In case of a microcontroller, the const data could be located in Read Only Memory.Define the ROM_ALLOC macro as it is required for allocating a variable in the read only memory.ROM_ALLOC is used only for the allocation of a ROM based variable. For other purposes see the ROM macro! If not specified it is defined automatically as:#define ROM_ALLOC ROM
|
GEN_PTR | General pointer type for memory and string manipulation libraries (<mem.h>, <string.h>). In ANSI-C the general pointer type in theese standard libraries is char* . However e.g MPLAB C18 uses void* in these libraries, causing compiler warnings.Define GEN_PTR according to your actual target's needs. If not specified it is defined automatically as: #define GEN_PTR char *
|
NO_RELATIVE_INCLUDE | Most compiler treats the include path relative to the actual file invoking the include command for local includes, regardless if it is a source or a header file.Some others always use the source file location as the base path for all local includes (e.g. MPLAB C18). This macro is not defined normally, define it if your compiler requires. |
NDEBUG | The usual way to distinguish between debug and release versions is defining the NDEBUG macro for the release version. Ooc uses this approach internally. However some compilers or IDEs use other macros for this purpose.Define NDEBUG macro according to your compiler / IDE, letting ooc be consistent. |
OOC_NO_THREADS | If defined then a single threaded version is built. You must define dummy threading primitives in case of a single threaded version, as well! See Threading primitives. |
NO_INLINE | If defined then it indicates that the comlpiler does not support function inlining. See Inline control. |
OOC_NO_DYNAMIC_MEM | On some microcontroller targets the dynamic memory allocation is not available. On those targets every Object must be statically allocated, and thus the ooc_new() and ooc_delete() is nonsence. Defining OOC_NO_DYNAMIC_MEM ooc is compiled without the need for dynamic memory handling, and thus has some limitations as well: any function related to dynamic memories is unavailable. |
OOC_NO_FINALIZE | On microcontroller targets there is usually no normal shutdown or program exit: those programs are running continuously and never exit. In such environments the class finalization is more than meaningless: defining this macro will save three pointers per class definitions and remove the ooc_finalize_class() and ooc_finalize_all() functions from the build. (A good optimizing compiler should remove your class finalizing routines as well, since they are never reached.) |
_OOC_VTAB_INITIALIZER | On some microcontroller targets it is important to place the virtual table into the initialized data section. We van force this behaviour by defining this macro. (Se mcc18.h port file!) Although ANSI-C says that all uninitialized data is set to 0 at program start, this macro could be necessary on small microcomputers, since they do not clean their uninitialized data section at start up or restrat. |
OOC_HAS_UNIX_SIGNALS | The TestCase class converts some Unix signals (SIGSEGV, SIGFPE) into ooc Exceptions letting us to do unit test checks way much easier. This macro indicates that there are unix signals implemented in the operation system. |
The standard C library on the host must support the following minimal set compatible with ANSI-C:
The following headers must be available:
The following memory handling functions must be available:
(This is not an extra requirement :-) If your host does not support these functions then you must implement them.)