0

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?

Big Guy
  • 33
  • 6
  • The more I read the more it seems that the problem is artificial and created by poor design. Instead of focusing on what tools to use, focus on what the program should actually do and then design the program accordingly, picking suitable tools during the implementation phase. – Lundin Mar 08 '23 at 07:45
  • That would be nice, but sometimes these things are a requirement and you do your best to work within the bounds given you :) – Big Guy Mar 09 '23 at 15:24

1 Answers1

3

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.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • This is however incredible memory-inefficient. – Lundin Mar 08 '23 at 07:40
  • Maybe they could have to embed the union/struct, with a 'type' identifier, just to know which of the struct is filled. The identifier can even be the first element of each original struct, common to all of them - I think I've seen this approach more than once. – LuC Mar 08 '23 at 09:56