Objective
- Create a generic interface with default implementations of each function pointer used in the interface.
- This is desired in part so that we never have a null pointer reference when using an interface function pointer.
- Support multiple "instances" of this interface (particularly for different implementations of this interface).
- This means that we should be able to create generic interface instance of type A and a generic interface instance of type B where either instance may have function pointers using default definitions.
Result
I am using weak aliases for the default implementations however it seems as though this does not allow me to have multiple implementations of my interface and when I try to compile them in either I get static declaration follows non-static declaration
errors. Removing the static
keyword results in multiple definition
errors.
Example code
My interface, specific and default implementation can be simplified to the following example.
dfltDef_Header.h
#ifndef __DEFAULTDEF_H_
#define __DEFAULTDEF_H_
#include <stdint.h>
#include <stdbool.h>
#define _weak_alias(old, new) \
extern __typeof(old) new __attribute__((weak, alias(#old)))
typedef struct {
int (*getVal)(void);
bool (*isTrue)(void);
} myIF_t;
int getVal(void);
bool isTrue(void);
#endif // __DEFAULTDEF_H_
dfltDef_impl.c
#include <stdint.h>
#include <stdbool.h>
#include "dfltDef_header.h"
bool dflt_isTrue(void) {
return true;
}
int dflt_getVal(void) {
return 3;
}
_weak_alias(dflt_isTrue, isTrue);
_weak_alias(dflt_getVal, getVal);
someInterfaceImpl.h
#ifndef __SOMEINTERFACEIMPL_H_
#define __SOMEINTERFACEIMPL_H_
#include "dfltDef_header.h"
myIF_t *getInterface(void);
#endif // __SOMEINTERFACEIMPL_H_
someInterfaceImpl.c
#include "someInterfaceImpl.h"
#include "dfltDef_header.h"
bool isTrue(void) {
return false;
}
static myIF_t thisInterface = {
.getVal = getVal,
.isTrue = isTrue,
};
myIF_t *getInterface(void) {
return &thisInterface;
}
anotherInterfaceImpl.h
#ifndef __ANOTHERINTERFACEIMPL_H_
#define __ANOTHERINTERFACEIMPL_H_
#include "dfltDef_header.h"
myIF_t *getOtherInterface(void);
#endif // __ANOTHERINTERFACEIMPL_H_
anotherInterfaceImpl.c
#include "anotherInterfaceImpl.h"
#include "dfltDef_header.h"
static int getVal(void) {
return 1;
}
static myIF_t thisInterface = {
.getVal = getVal,
.isTrue = isTrue,
};
myIF_t *getOtherInterface(void) {
return &thisInterface;
}
dflDef_App.c
#include "dfltDef_header.h"
#include "someInterfaceImpl.h"
#include "anotherInterfaceImpl.h"
int main() {
/* DFLT_FUNC(getVal) */
myIF_t *IF = getInterface();
printf("%d %d\n", IF->isTrue(), IF->getVal());
myIF_t *otherIF = getOtherInterface();
printf("%d %d\n", otherIF->isTrue(), otherIF->getVal());
return 0;
}
When compiled with
gcc dflDef_App.c someInterfaceImpl.c anotherInterfaceImpl.c dfltDef_impl.c -o dfltExample
I get the following:
anotherInterfaceImpl.c:4:12: error: static declaration of ‘getVal’ follows non-static declaration
4 | static int getVal(void) {
| ^~~~~~
In file included from anotherInterfaceImpl.h:3,
from anotherInterfaceImpl.c:1:
dfltDef_header.h:13:5: note: previous declaration of ‘getVal’ was here
13 | int getVal(void);
| ^~~~~~
Key questions
- Is there a way to use static function definitions to override weak aliases?
- Can I make one strong symbol hidden from the others (via static libraries or otherwise)?
- Is this simply not possible or bad practice ?
It would be great to do this in such a way that the interface function definitions can only be used via the interface and if non is defined then we fall back on the default definition. Any and all help/advise is much appreciated.
Aucun commentaire:
Enregistrer un commentaire