Last active
December 18, 2020 07:53
-
-
Save FedeDP/ef0150580ff15dd22ffa5a7d58a0150d to your computer and use it in GitHub Desktop.
Stupidly simple set of macros to mimic GO-like INTERFACE in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stddef.h> | |
#include <string.h> | |
/* | |
* PROs: | |
* * can have variables too as interface members | |
* | |
* CONs: | |
* * INTERFACE type can be directly declared and used as a normal struct | |
* * INTERFACE_EMBED() macros injects a field in the struct | |
*/ | |
#define INTERFACE(interface, ...) typedef struct { __VA_ARGS__ } interface | |
#define INTERFACE_EMBED(interface) interface _interface | |
#define INTERFACE_OF(ptr, interface) ((interface *)ptr + offsetof(typeof(*ptr), _interface)) | |
#define INTERFACE_INIT(ptr, interface, ...) memcpy(INTERFACE_OF(ptr, interface), &(interface){ __VA_ARGS__ }, sizeof(interface)); | |
static void foo(void); | |
// Declare the interface, in this case named "test" with 2 fields, an int and a function pointer | |
INTERFACE(test, | |
int val; | |
void (*cb)(void); | |
); | |
// Declare a struct that implements "test" interface. | |
// Note, test interface member must still be initialized. | |
typedef struct { | |
int bar; | |
double x; | |
INTERFACE_EMBED(test); | |
} myS; | |
static void foo(void) { | |
printf("World\n"); | |
} | |
static void my_test(test *t) { | |
printf("Hello %d!\n", t->val); | |
t->cb(); | |
} | |
int main() { | |
myS t = {0}; | |
// Init interface members | |
INTERFACE_INIT((&t), test, 5, foo); | |
// Call a function on interface | |
my_test(INTERFACE_OF((&t), test)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment