Plugin architecture design by C

Plugin architecture design by C


Table of Contents

  • 1 How to make a plugin architecture in C?
  • 2 Problems I met
  • 3 How I solve this problem?
  • 4 Pros and Cons of plugin architecture.

1 How to make a plugin architecture in C?

The plugin architecture is a great design in order to make extensible and resilience software. The software's modules were loaded dynamically from the plugin modules at running time. In C language, this architecture can be implemented by dlopen which is the programming interface to the dynamic linking loader in Linux. 

In other words, A software is split into separate modules which are compiled and linked into shared libs. And the software can load the shared libs into memory dynamically, this is what I wanna genesis to be. genesis is a reactor architecture middleware lib that I am working on.

2 Problems I met

In order to make a plugin architecture, I use dlopen API to implement plugin modules. But I met some troubles in the development, the shared libs, or the modules, should not depend on other libs. In other words, the dlopen will fail when loading the libs which invoking the symbols that not belong to it. 

So the modules should be developed independently of the other parts of the source code. Include the data structure in the header file is fine, but invoke the functions can make the dlopen fail. 

dlopen have two flags to control its behavior – RTLD_LAZY, RTLD_NOW. when you use the RTLD_NOW flag, dlopen just return a none handler when you make above mistakes, while when to use the RTLD_LAZY flag, dlopen can return the handler, but it reports an error named "can not find symbol" at running time.

3 How I solve this problem?

Take the genesis's reactor class, for example, I write another header file reactor-internal.h, which export the reactor class's details to outside. But this way damage the encapsulation partly. 

// reactor.h
#ifndef _REACTOR_H
#define _REACTOR_H

#include "typedef.h"
#include "config.h"
#include "allocator.h"

DECLES_BEGIN

struct _Reactor;
typedef struct _Reactor Reactor;

Reactor* reactor_create(Config* config, Allocator* alloc);

Ret reactor_run(Reactor* thiz);
Ret reactor_stop(Reactor* thiz);

void reactor_destroy(Reactor* thiz);

DECLES_END

#endif /* _REACTOR_H */
// reactor-internal.h
#ifndef _REACTOR_INTERNAL_H
#define _REACTOR_INTERNAL_H

#include "typedef.h"
#include "reactor.h"
#include "main_loop.h"
#include "modules_manager.h"
#include "sources_manager.h"
#include "logger.h"

DECLES_BEGIN

struct _Reactor {
    Logger* logger;
    Allocator* alloc;
    Config* config;
    SourcesManager* sources_manager;
    ModulesManager* modules_manager;
    MainLoop* main_loop;
};

Ret reactor_get_main_loop(Reactor* thiz, MainLoop** main_loop);
Ret reactor_set_main_loop(Reactor* thiz, MainLoop* main_loop);

Ret reactor_get_modules_manager(Reactor* thiz, ModulesManager** modules_manager);
Ret reactor_set_modules_manager(Reactor* thiz, ModulesManager* modules_manager);

Ret reactor_get_sources_manager(Reactor* thiz, SourcesManager** sources_manager);
Ret reactor_set_sources_manager(Reactor* thiz, SourcesManager* sources_manager);

DECLES_END

#endif /* _REACTOR_NTERNAL_H */


Another way to solve this problem is to link the reactor's object file into the plugin modules. It's the most efficiently way, but so ugly.

4 Pros and Cons of plugin architecture.

Here is my point, the pros of plugin architecture in C is that it provided the extensible architecture in software design, the cons of the plugin architecture are that it destroy the OOP principle. 

So the highly OOP style C code is not suitable for using plugin architecture, and plugin architecture oriented C code lack the OOP style. But one of the fabulous features of C code is that it not bound to OOP principles, OOP is just some thoughts in software development. So the pros .vs. cons, well… 

Comments

  1. Wow, thank you dude, really! I was looking for it...

    ReplyDelete

Post a Comment

Popular posts from this blog

Bluedroid stack in android

How to setup a NAT server?

Network programming in elisp