A static library that can receive any struct via void *
and is able to access it's member variables whether an embedded struct or a pointer to a function.
It's guaranteed that a member variable which is an embedded struct will be there and is accessible via super
and a member variable which is a pointer to a function will be available called execute
.
Question - (in short how to access underlying struct members using void *
only)
I guess it's related to generic programming, can we somewhow access the following via memory addresses or any other alternate way. casting to specific structure is not available at compile time struct will sure have an execute pointer function and super variable. Guaranteed.
// from src/library.c (someStruct a void *, casting to specific struct is not available)
someStruct->execute();
someStruct->super->execute();
Attempt 1 Reference
struct Super *pointer = someStruct + 8; // works
pointer->execute(); // prints overridden method!
// how to access second member which is a pointer to function
Open to any form of solutions whether it's going low level to memory addresses to access each member or any other alternate way.
Expected Output:
overridden method!
super method
src/library.h
#ifndef POLY_LIBRARY_H
#define POLY_LIBRARY_H
struct Library {
void (*passSomeStruct)(void *someStruct);
};
struct Library *newLibrary();
#endif
src/library.c
#include "library.h"
#include <stdlib.h>
void passSomeStruct(void *someStruct) {
// can we somewhow access the following via memory addresses or any other alternate way.
// casting to specific structure is not available at compile time
// struct will sure have an execute pointer function and super variable
someStruct->execute();
someStruct->super->execute();
}
struct Library *newLibrary() {
struct Library *library = malloc(sizeof(struct Library));
library->passSomeStruct = passSomeStruct;
return library;
}
src/super.h
#ifndef POLY_SUPER_H
#define POLY_SUPER_H
struct Super {
void (*execute)();
};
struct Super *newSuper();
#endif //POLY_SUPER_H
src/super.c
#include "super.h"
#include <stdio.h>
#include <stdlib.h>
static void execute() {
printf("super method\n");
}
struct Super *newSuper() {
struct Super *super = malloc(sizeof(struct Super));
super->execute = execute;
return super;
}
Test
test/library_test.h
#ifndef POLY_LIBRARY_TEST_H
#define POLY_LIBRARY_TEST_H
#endif //POLY_LIBRARY_TEST_H
test/library_test.c
#include "../src/library.h"
#include "temp.h"
int main() {
struct Library *library = newLibrary();
struct Temp *temp = newTemp();
library->passSomeStruct(temp);
return 0;
}
test/temp.h
#ifndef TEST_SUPER_H
#define TEST_SUPER_H
#include <stdlib.h>
struct Temp {
struct Super *super;
void (*execute)();
};
struct Temp *newTemp();
#endif //TEST_SUPER_H
test/temp.c
#include "temp.h"
#include <stdio.h>
#include "../src/super.h"
static void execute() {
printf("overridden method!\n");
}
struct Temp *newTemp() {
struct Temp *temp = malloc(sizeof(struct Temp));
temp->super = newSuper();
temp->execute = execute;
return temp;
}
MakeFile
VPATH := src test
all: libTest
libTest: super.o library.o
mkdir -p bin
ar rcs bin/libTest $^
test: library_test
./library_test
library_test: library_test.o library.o super.o temp.o
$(CC) -o $@ $^
%.o: %.c %.h