Search code examples
cembeddeddriverwrapper

Encapsulation in driver wrapper using an abstract struct


I wanna ask, if this is a valid approach for my driver wrapper encapsulation or if there is a better way. My target is to hide the handle of the underlying driver, so the header does not include the driver library.

//wrapper_foo.h
typedef struct WrapperCtrl WrapperCtrl;
typedef WrapperCtrl *WrapperHandle;

WrapperHandle wrapper_open_device();

//wrapper_foo.c
#include "wrapper_foo.h"
#include "driver.h"
#include <stdint.h>



struct WrapperCtrl {
    uint8_t wrapper_specific_parameter;
    driver_handle handle;
};

static WrapperCtrl wrapper_cfg;



WrapperHandle wrapper_open_device() {
    WrapperHandle w_handle = &wrapper_cfg;
    w_handle->handle = driver_open_device(); 
    if (w_handle->handle == NULL) {
        return NULL;
    } else {
        return w_handle;
    }
}

Thanks for help and advise!


Solution

  • It is widely considered good encapsulation practice in C to declare but not define a struct in a header and to keep the definition private. This is especially useful if some of the members of the struct are types which require including extra headers that you do not want to include elsewhere.

    However, many open source projects written in C (such as linux) have coding standards which forbid to typdef a struct and forbid to typedef a pointer. They say that it is important that the person using your code knows what is a pointer and what is a compound type so you should not try to hide this.

    Opinions on this differ, and what you have done is (or at least used to be) common practice in windows based code, so you should consider what is the common style in the industry where this code will be used.

    Finally, having a function that returns a pointer to static data is fairly common in C applications, but it does limit the expandability of your code and possibly prevent it from being re-used as a library. You need to think carefully whether there is really only going to only ever be one instance of this type. Maybe you need to have a pair of functions which allocate and release instances of this type using heap memory.