4

I'm trying to create a modular interface in my C project that would allow source files to be built selectively and be added and removed without having to change any of the project's core components. I have searched all of the web for a method on how to do this and cannot find anything.

My guess at this stage, would involve something along the lines of each module having it's own source and header files (module_1.c, module_1.h, module_2.c, module_2.h, etc). Each module would likely have to have a structure containing pointers to the needed functions like:

struct module_def {
  char *name;
  void (*module_init) (void);
  void (*module_shutdown) (void);
};

I believe that an array of these definition structures would then need to be accessible by the core code. I just don't know how to have such an array (or anything similar) be generated automatically using a list of enabled modules without resorting to a messy script that creates a new source file containing a list of all the structures during the build process.

At least, that's how I believe this should work.

Ultimately, I'm looking for a way to create a modular coding interface in C that would allow separate modules (source or object files, it doesn't matter) to be selectively linked during build and called by the main application. This is for an embedded solution so dynamic loading, shared libraries, etc cannot work.

Jake
  • 183
  • 5
  • What's wrong with having *one* source file that contains `#ifdef / #endif` guarded module_defs *in a table*; then you link the objects from a library (such as `.a`), a POSIX-style linker wouldn't link those objects with no references to it at all in... – Antti Haapala -- Слава Україні Oct 16 '17 at 10:36
  • There is no way to do this portably in C. See this question and answer for a method that is not portable: https://stackoverflow.com/questions/11840651/how-can-i-implement-a-dynamic-dispatch-table-in-c/11844418#11844418 – Art Oct 16 '17 at 11:04

1 Answers1

1

With gcc, you can use something like that:

(for example in foo_module.c)

struct module_def foo_module {
    ...
};

static void init_module(void) __attribute__ ((constructor));

static void init_module(void) {
    register_my_module(&foo_module);
}

You can put this in each of your module files and your init_module-functions should be called at initialization time (i.e. when the bss is cleared etc, before the main code starts).

Note that this is not portable, but will do well with many embedded platforms, e.g. with avr-gcc and the like.

Ctx
  • 18,090
  • 24
  • 36
  • 51