I know reflection is not possible in C, but I have a unique issue in an embedded environment that can only allocate memory at init time.
We are using an embedded version of 0MQ and nanopb for communication between several microservices, where one microservice is a "data backbone" that stores IO for the other microservices. The other microservices read data from the "data backbone" service, process it, and then send the result back to the "data backbone" service.
We are trying to keep the "data backbone" service as ignorant of the other services as possible by just consuming protobuf messages and returning protobuf messages when requested. However when a computing service requests data from the "data backbone", the "data backbone" needs some way to know what to return.
Since the protobuf's are defined in nanopb protobuf generated .h files, we are trying to think of some way for the computing services to say, give me data x, y, z, and the "data backbone" to be able to use the correct protobuf definitions and return that data.
We are trying to think of a way for a microservice to register itself with the "data backbone" service, to give it a list of protobufs that it is expecting on request so that the "data backbone" can just see that microservice X is requesting data X,Y,Z,etc and it returns the data in the appropriate protobufs.
Without something like reflection, how can we achieve this in C - is there a way to instantiate structs based on perhaps a unique ID using macros, or something like that? Can we have the other microservices register with the data backbone at init (where malloc is allowed), so that the data backbone can instantiate protobuf structs then, and then populate and transfer that data on request?
You can create a union of all struct types and create an array of the union at file scope.
union all_structs {
struct x x;
struct y y;
struct z z;
};
// some maximum number of element in the list
#define MAXLIST 1000
union all_structs struct_list[MAXLIST];
Then anytime you need to instantiate a struct, you can grab an element from the list and use it for any of the types contained in the union.