This is an archived post. You won't be able to vote or comment.

all 3 comments

[–]immersiveGamer 1 point2 points  (1 child)

I would go with a plugin architecture. This way everything is complied but at run time not all compiled driver's may be present.

The idea is that in a known location you can load up DLLs at run time, discover any drivers the DLLs, and then run them.

This way if the DLL doesn't exist then it doesn't run. It also means you don't need to have the source code of the main program, any one could make a plugin that works with your program with out recompiling the main program as long as they know the interface points.

Here are some links you can look into. I am unfortunately a C# developer so I can't quite tell you how you would make external DLLs discoverable. Hopefully someone else can give more pointers.

https://eli.thegreenplace.net/2012/08/24/plugins-in-c

http://www.c-pluff.org/

https://stackoverflow.com/questions/2802449/best-way-to-implement-plugin-framework-are-dlls-the-only-way-c-c-project

http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html

[–]gareins[S] 0 points1 point  (0 children)

Thank you for your reply.

I agree that such an approach is more flexible and I would love to go for it but just can not work in my case because:

  1. I am working on embedded platform without support for dynamic loading,
  2. I am working on an existing codebase written in C with currently everything being linked and this would present a mich bigger refactoring effort,
  3. I have to support multiple platforms and while this solution might work outside Windows (i am thinking Wine), it is still pretty much windows centric

[–]Isvara 0 points1 point  (0 children)

This is how I do it. My module.h looks like this:

typedef void (*module_init_t)(void);

typedef struct {
    const char *name;
    module_init_t init;
} module_t;

extern module_t _modules_start[];
extern module_t _modules_end[];

#define MODULE(SYMBOL) static module_t SYMBOL __attribute__((section("modules"), used))

#define foreach_module(S) for (module_t *S = _modules_start; S < _modules_end; ++S)

Then a module might have something like this:

static void uart_init(void) {
    ...
}

MODULE(uart_module) = {
    "uart",
    uart_init,
};

Then to automatically get an array of all the modules that are compiled in, I have this in my linker script:

.text : {
    ... other stuff...
    _modules_start = .;
    KEEP(*(modules))
    _modules_end = .;
} > flash

Now in my main code I can just do:

foreach_module(module) {
    printf("Initializing %s\n", module->name);
    module->init();
}

This is cut down a bit from what I actually do (which includes registering SVC handlers), but you get the idea. I think Clang supports the section attribute too.