-1

First off, to clear some confusion, by 'module based program with intelligent linking' I mean having an adapter class intelligently inherit individual header files through a 'plug-n-play' type system. This system needs to consist of a simple folder called for example 'Modules', and all that the user needs to do to activate a module is drag and drop the header and source file of that module into the folder. I believe that I will need to utilize some scripting language to generate required text, such as #includes, in the adapter file. Also I do not know much about Dynamic Link Libraries, but I would prefer to use them if possible (They would need to produce the same effect of course).

For an example, lets say I have my main here:

moduleAdapter->Initialize();

while (true)
{
    moduleAdapter->Update();
    moduleAdapter->Render();
}

moduleAdapter->Release();

This loop should be able to pass update and render function calls to all of the linked modules.

Next, an example empty module file called 'module0.h', I could have something like this:

class Module0
{
public:
    void Initialize();
    void Update();
    void Render();
    void Release();
}

I am targeting Windows, but multi platform would be great. That said, any scripting language that would work on at least Windows, OSX, and Unix would be perfect.

What I need and don't understand how to do is this; What can I make/do for an 'adapter' that manages the modules and processes their input and output, and what kind of script could I make and use to do this. I am assuming that I will need the script to manually edit the files to write in the #includes and such.

Thank you in advance.

Xenonic
  • 346
  • 2
  • 3
  • 20

2 Answers2

1

You could use an interface ( a pure virtual common parent class), the pimpl idiom to hide the implementation and a dynamically loaded factory function to instantiate the module from the dll.

There won't be any need of headers, as your main program uses the modules known interface via polymorphism.

The only non cross-platform thing would be loading the DLL and calling the dynamically loaded factory function.


Check Cross-Platform C++ Dynamic Library Plugin Loader for cross platform solutions.

Community
  • 1
  • 1
xvan
  • 4,554
  • 1
  • 22
  • 37
  • Thank you for the answer, but I have a quick question since I have not had experience with this before. Would you solution work still as a 'plug-n-play' experience, would the application be able to intelligently find and link the DLL without given user input? – Xenonic Apr 25 '16 at 01:55
  • If you have a plugin install folder, you just need to scan that path, and load all the DLL's there (Windows LoadLibrary ). [Here's and example](http://stackoverflow.com/a/8696688/1477064) – xvan Apr 25 '16 at 03:07
  • I'm going to give you the answer on this one as I don't have the time for implementation at the moment, so thank you for your time and effort. – Xenonic Apr 25 '16 at 03:14
0

Here is what I have. Following solutions assumes that:

  1. You always have 1 module
  2. Your modules have single interface represented by parent class
  3. You have written the code and only need to include and link proper files

The solution is based on make utility, which can be found in MinGW or Cygwin environments. It also assumes your make can run your compiler and that your compiler is g++. The last requirement can be probably lifted, as MS compiler can be used from make too, but I don't know how.

Following files form the minimal project:

  • main.cpp contains your common code (your while loop from example)
  • p1 and p2 are project (module) directories (referred to as DIR)
  • DIR/derived.h are respective module headers you want to #include
  • DIR/derived.cpp are respective module files you want to link with
  • base.h declares modules' parent class - the interface
  • Makefile is make's source file

main.cpp

#include "base.h"
#include "derived.h"

int main(void) {
    Base * module = new Derived();

    module->work();
}

p1/derived.h

#pragma once
#include <iostream>
#include "../base.h"

class Derived : public Base {
public:
    void work();
};

p2/derived.h is identical to p1/derived.h

p1/derived.cpp

#include "derived.h"

void Derived::work() {
    std::cout << "I am P1 module" << std::endl;
}

p2/derived.cpp

#include "derived.h"

void Derived::work() {
    std::cout << "I am P2 module" << std::endl;
}

base.h

#pragma once
#include <iostream>

class Base {
public:
    virtual void work() = 0;
};

Makefile

PROJECT ?=
SRCS    = main.cpp $(PROJECT)/derived.cpp
OUTPUT  = proj.exe

$(OUTPUT): $(SRCS)
    $(CXX) -I$(PROJECT) -o $@ $^

You run compilation with make PROJECT=<PROJECT>. For example, make PROJECT=p1 causes following command to be run

g++ -Ip1 -o proj.exe main.cpp p1/derived.cpp

which correctly compiles main.cpp with p1/derived.cpp into proj.exe executable. Running it results in "I am P1 module" being printed, which is expected behavior.

Honza Remeš
  • 1,193
  • 8
  • 11
  • Ok, so I like your approach, but I want to make sure that the user has absolutely no need to even open any of the files. I'm sorry I didn't specify in my post, I will edit it now. – Xenonic Apr 25 '16 at 00:30
  • The user only specifies the PROJECT= for `make`. But it's possible you need something completely different from what the solution in my answer is for. – Honza Remeš Apr 25 '16 at 00:35