From 0f595e076f03c02b366901e8d3c5cc0c50681108 Mon Sep 17 00:00:00 2001 From: Max Christian Pohle Date: Tue, 23 Aug 2016 02:46:27 +0200 Subject: generic plugin manager example, fully working --- Makefile | 26 +++++++++++++ main.cpp | 40 +++++++++++++++++++ pluginmanager.hpp | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ plugins/plugin.hpp | 39 +++++++++++++++++++ plugins/plugin_test1.cpp | 35 +++++++++++++++++ plugins/plugin_test1.hpp | 33 ++++++++++++++++ plugins/plugin_test2.cpp | 24 ++++++++++++ plugins/plugin_test2.hpp | 34 +++++++++++++++++ plugins/plugin_test3.cpp | 24 ++++++++++++ plugins/plugin_test3.hpp | 34 +++++++++++++++++ 10 files changed, 388 insertions(+) create mode 100644 Makefile create mode 100644 main.cpp create mode 100644 pluginmanager.hpp create mode 100644 plugins/plugin.hpp create mode 100644 plugins/plugin_test1.cpp create mode 100644 plugins/plugin_test1.hpp create mode 100644 plugins/plugin_test2.cpp create mode 100644 plugins/plugin_test2.hpp create mode 100644 plugins/plugin_test3.cpp create mode 100644 plugins/plugin_test3.hpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d6ce077 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +FILENAME = pluginmanager + +all: all_plugins executable + @echo "> MAKING ALL..." + +test: all + @echo "> TESTING PLUGIN1..." + ./$(FILENAME) ./plugin1.so + @echo "> TESTING PLUGIN2..." + ./$(FILENAME) ./plugin2.so + @echo "> TESTING PLUGIN3..." + ./$(FILENAME) ./plugin3.so + +clean: + @echo "> CLEANING..." + rm $(FILENAME) + rm *.so + +all_plugins: + @echo "> MAKING PLUGINS..." + $(CXX) $(CXXFLAGS) -shared -fPIC -o plugin1.so plugins/plugin_test1.cpp + $(CXX) $(CXXFLAGS) -shared -fPIC -o plugin2.so plugins/plugin_test2.cpp + $(CXX) $(CXXFLAGS) -shared -fPIC -o plugin3.so plugins/plugin_test3.cpp + +executable: + $(CXX) $(CXXFLAGS) -o $(FILENAME) main.cpp -ldl diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..9f442cb --- /dev/null +++ b/main.cpp @@ -0,0 +1,40 @@ +/* + * main.cpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include "pluginmanager.hpp" + +using namespace std; +int main(int argc, char* argv[]) +{ + typedef Plugin* create(); + string plugin = string(argv[1]); + try + { + PluginManager *pm = new PluginManager(); + pm->load_plugin(plugin); + Plugin* p = pm->get_instance(plugin); + cout << "> VERSION: " << p->get_version() << endl << endl; + p->dosomething(); + } + catch(char* e) + { cout << e << endl; } +} diff --git a/pluginmanager.hpp b/pluginmanager.hpp new file mode 100644 index 0000000..2415acf --- /dev/null +++ b/pluginmanager.hpp @@ -0,0 +1,99 @@ +/* + * pluginmanager.hpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef pluginmanager +#define pluginmanager + #define PLUGIN_ENGINE_VERSION 1 + + #include + #include + #include + #include + #include + #include + + #include "plugins/plugin.hpp" + + using namespace std; + + template + class PluginManager + { + private: + int engine_version; + typedef T create(); + map plugins; + typename map::iterator iter; + + public: + PluginManager() : engine_version(PLUGIN_ENGINE_VERSION) {} + + T get_instance(string t) + { + iter = plugins.find(t); + if (iter != plugins.end()) + { return iter->second(); } + } + + list list_plugins() + { + list retval; + for(iter=plugins.begin(); iter!=plugins.end(); ++iter) + { retval.push_front(iter->first); } + return retval; + } + + void load_plugin(string filename) + { + std::stringstream serr; + char* dlsym_error; + std::cerr << "\n> OPENING " << filename << "..."; + void* plugin2open = dlopen(filename.c_str(), RTLD_LAZY); + if (dlsym_error = dlerror()) + { + std::stringstream a; + a << + std::string(filename) << + std::string(" is not a valid plugin\n\t") << + std::string(dlsym_error); + throw (char*) a.str().c_str(); + } + else + { + std::cerr << "done.\n"; + } + + create* f_creator = (create*) dlsym(plugin2open, "create"); + if (dlsym_error = dlerror()) + { + throw (char*)"plugin has no creation-interface" + ", so is obviously no subclass of 'Plugin'"; + } + else + { + std::cout << "> LOADING " << filename << "..."; + plugins.insert(make_pair(filename, f_creator)); + std::cout << "done.\n"; + } + } + }; + +#endif diff --git a/plugins/plugin.hpp b/plugins/plugin.hpp new file mode 100644 index 0000000..9a354c2 --- /dev/null +++ b/plugins/plugin.hpp @@ -0,0 +1,39 @@ +/* + * plugin.hpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef PLUGIN_HPP +#define PLUGIN_HPP + #include + #include + #include + #include + + using namespace std; + class Plugin + { + private: + int version; + public: + //Plugin() : version(0) + virtual const int get_version() = 0; + virtual void dosomething() = 0; + }; +#endif diff --git a/plugins/plugin_test1.cpp b/plugins/plugin_test1.cpp new file mode 100644 index 0000000..e02612c --- /dev/null +++ b/plugins/plugin_test1.cpp @@ -0,0 +1,35 @@ +/* + * plugin_test1.hpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "plugin_test1.hpp" + +plugin_test::plugin_test() +{ std::cout << "constructor of plugin I.\n"; } + +void plugin_test::dosomething() +{ std::cout << "teste dosomething in plugin I.\n"; } + +const int plugin_test::get_version() +{ return VERSION; } + +// the class factories +extern "C" plugin_test* create() +{ return new plugin_test; } + diff --git a/plugins/plugin_test1.hpp b/plugins/plugin_test1.hpp new file mode 100644 index 0000000..ec7597d --- /dev/null +++ b/plugins/plugin_test1.hpp @@ -0,0 +1,33 @@ +/* + * plugin_test1.hpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef PLUGIN_TEST1_HPP +#define PLUGIN_TEST1_HPP + +#include "plugin.hpp" +#define VERSION 3 +class plugin_test : public Plugin +{ + public: + plugin_test(); + const int get_version(); + virtual void dosomething(); +}; +#endif diff --git a/plugins/plugin_test2.cpp b/plugins/plugin_test2.cpp new file mode 100644 index 0000000..1dbbf7b --- /dev/null +++ b/plugins/plugin_test2.cpp @@ -0,0 +1,24 @@ +/* + * plugin_test2.cpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "plugin_test2.hpp" + +void plugin_test::dosomething() +{ std::cout << "teste dosomething in plugin II.\n"; } diff --git a/plugins/plugin_test2.hpp b/plugins/plugin_test2.hpp new file mode 100644 index 0000000..1291b18 --- /dev/null +++ b/plugins/plugin_test2.hpp @@ -0,0 +1,34 @@ +/* + * plugin_test2.hpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "plugin.hpp" +#define VERSION 2 +class plugin_test : public Plugin +{ + public: + plugin_test() + { std::cout << "Das ist plugin nummer II.\n"; } + const int get_version() + { return VERSION; } + void dosomething(); +}; + +extern "C" Plugin* create() +{ return new plugin_test(); } diff --git a/plugins/plugin_test3.cpp b/plugins/plugin_test3.cpp new file mode 100644 index 0000000..39c4988 --- /dev/null +++ b/plugins/plugin_test3.cpp @@ -0,0 +1,24 @@ +/* + * plugin_test3.cpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "plugin_test3.hpp" + +void plugin_test::dosomething() +{ std::cout << "teste dosomething in plugin III.\n"; } diff --git a/plugins/plugin_test3.hpp b/plugins/plugin_test3.hpp new file mode 100644 index 0000000..a057d8f --- /dev/null +++ b/plugins/plugin_test3.hpp @@ -0,0 +1,34 @@ +/* + * plugin_test3.hpp + * + * Copyright 2009 Max Christian Pohle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "plugin.hpp" +#define VERSION 1 +class plugin_test : public Plugin +{ + public: + plugin_test() + { std::cout << "Das ist plugin nummer III.\n"; } + const int get_version() + { return VERSION; } + void dosomething(); +}; + +extern "C" Plugin* create() +{ return new plugin_test(); } -- cgit v1.2.3