Home

Awesome

PLOOC (Protected Low-overhead Object-Oriented Programming with ANSI-C) v4.6.4

Introduction


Protected Low-overhead Object-Oriented Programming with ANSI-C, known as PLOOC ['plu:k], is a set of well-polished C macro templates that:

NOTE: This protection can be disabled by defining the macro __OOC_DEBUG__ to facilitate debugging.

NOTE: The overhead is nearly ZERO. The template fully utilizes ANSI-C's enforced compilation rules to deliver object-oriented features with minimal necessary cost.

    - Suitable for both bare-metal and RTOS environments.
    - Suitable for both 8-bit and 32-bit MCUs.

What Makes PLOOC Different from Other OOCs?

The concept of Object-Oriented C (OOC) is not new. There are numerous libraries, SDKs, and templates that extend ANSI-C with object-oriented programming features. Although PLOOC emphasizes its low overhead in both code size and performance, many macro-based OOC solutions also offer low overhead. PLOOC does not force you to use heap or pool memory management, nor does it provide garbage collection (GC) features, leaving these options to the user. This makes it suitable even for 8-bit systems. While some might see this as a drawback, it is a deliberate design choice. I won't argue about this.

So, what really sets PLOOC apart from the others? Is it simply another reinvented wheel?

The answer is NO.

PLOOC introduces a unique feature that most other solutions lack: it ensures that a class's private members are truly private and protected. This means that users outside of the class source code are prevented from accessing these private members. Instead, they see only a solid block of memory, masked as a byte array. Since classes in C are mimicked by structures, PLOOC implements classes using a masked structure. As expected, only the class source code can access the private members, and only the class source code of a derived class can access the protected members of the base class. Public members, however, are accessible to everyone.

How does this work? You might have guessed it from the term "masked structure." Essentially, it's a type-cheating trick in the header files.

This trick works well until it encounters a strict type-checking compiler. The most famous (or notorious) example is IAR, especially when multi-file compilation mode is enabled. No type-cheating trick can survive the rigorous checks of IAR's multi-file compilation mode.

//! The original structure in the class source code
struct byte_queue_t {
    uint8_t   *pchBuffer;
    uint16_t  hwBufferSize;
    uint16_t  hwHead;
    uint16_t  hwTail;
    uint16_t  hwCount;
};

//! The masked structure: the class byte_queue_t in the header file
typedef struct byte_queue_t {
    uint8_t chMask [sizeof(struct {
        uint8_t   *pchBuffer;
        uint16_t  hwBufferSize;
        uint16_t  hwHead;
        uint16_t  hwTail;
        uint16_t  hwCount;
    })];
} byte_queue_t;

To make this work, you must ensure that the class source code does not include its own interface header file. You can even go further if you're serious about the content:

//! The masked structure: the class byte_queue_t in the header file
typedef struct byte_queue_t {
    uint8_t chMask [sizeof(struct {
        uint32_t        : 32;
        uint16_t        : 16;
        uint16_t        : 16;
        uint16_t        : 16;
        uint16_t        : 16;
    })];
} byte_queue_t;

NOTE: The above code snippets are provided to illustrate the underlying scheme but are not practical, as the original structure's alignment is missing when creating the mask array. To solve this, you need to extract the alignment information using the __alignof__() operator and set the mask array's alignment attribute accordingly using __attribute__((aligned())).

PLOOC provides the "private-protection" feature with a different scheme, rather than relying on type-cheating. This allows it to support almost all C compilers with C99 features enabled. As the author, I must confess that it took considerable time to figure out how to deal with strict type-checking, and the initial scheme was both ugly and counterintuitive. Thanks to the inspiring contributions of Simon Qian, it took another three months to refine PLOOC into something elegant and simple. Henry Long's support was also crucial.

I hope you enjoy this unique approach to the challenges of object-oriented programming in C.

If you have any questions or suggestions, please feel free to let us know.

Update Log


License


The PLOOC library was written by GorgonMeducer(王卓然)embedded_zhuoran@hotmail.com and Simon Qian(钱晓晨)https://github.com/versaloon with support from Henry Long henry_long@163.com.

The PLOOC library is released under an open source license Apache 2.0 that allows both commercial and non-commercial use without restrictions. The only requirement is that credits is given in the source code and in the documentation for your product.

The full license text follows:

/*****************************************************************************
 *   Copyright(C)2009-2019 by GorgonMeducer<embedded_zhuoran@hotmail.com>    *
 *                       and  SimonQian<simonqian@simonqian.com>             *
 *         with support from  HenryLong<henry_long@163.com>                  *
 *                                                                           *
 *  Licensed under the Apache License, Version 2.0 (the "License");          *
 *  you may not use this file except in compliance with the License.         *
 *  You may obtain a copy of the License at                                  *
 *                                                                           *
 *     http://www.apache.org/licenses/LICENSE-2.0                            *
 *                                                                           *
 *  Unless required by applicable law or agreed to in writing, software      *
 *  distributed under the License is distributed on an "AS IS" BASIS,        *
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
 *  See the License for the specific language governing permissions and      *
 *  limitations under the License.                                           *
 *                                                                           *
 ****************************************************************************/

Contribution


Template

moduleContrinutor
plooc.hGorgonMeducer
plooc_class.hGorgonMeducer, Simon Qian
plooc_class_strict.hGorgonMeducer
plooc_class_back_box.hGorgonMeducer
plooc_class_simple.hSimon Qian
plooc_class_simple_c90.hGorgonMeducer

Examples

moduleContrinutor
How to define a classGorgonMeducer
How to access protected membersGorgonMeducer
How to implement PolymorphismGorgonMeducer

Applications / Projects which claim to use PLOOC


How to Use


Examples for PLOOC

Introduction

In order to show how PLOOC is easy and simple to use, examples are provided to demonstrate different aspects of the new OOPC method. Currently, the available examples are:

More examples will be added later...

LOG_OUT("\r\n-[Demo of overload]------------------------------\r\n");
LOG_OUT((uint32_t) 0x12345678);
LOG_OUT("\r\n");
LOG_OUT(0x12345678);
LOG_OUT("\r\n");
LOG_OUT("PI is ");
LOG_OUT(3.1415926f);
LOG_OUT("\r\n");

LOG_OUT("\r\nShow BYTE Array:\r\n");
LOG_OUT((uint8_t *)main, 100);

LOG_OUT("\r\nShow Half-WORD Array:\r\n");
LOG_OUT((uint16_t *)main, 100/sizeof(uint16_t));

LOG_OUT("\r\nShow WORD Array:\r\n");
LOG_OUT((uint32_t *)main, 100/sizeof(uint32_t));

example3