Freezedevil
Lieutenant
- Registriert
- Mai 2011
- Beiträge
- 645
Hi,
ich bin grade dabei auszuprobieren wie man eine Art Pluginmechanismus bewerkstelligen kann. Dazu habe ich eine abstrakte Klasse Scheduler erstellt von der dann die einzelnen "Plugins" erben und konkrete Strategien implementieren können. Damit später ohne Änderungen am Code zusätzliche Plugin benutzt werden können, sollen diese als Shared Object zur Laufzeit geladen werden. Meine Idee war also im Hauptprogramm einen Pointer vom Typ Scheduler auf die konkrete aktuell geladene Klasse zu haben. Allerdings sagt mir der Compiler, dass ich kein Objekt einer abstrakten Klasse anlegen kann, aber das versuche ich nach meinem Verständnis ja auch gar nicht. Eventuell sieht jemand von euch den Fehler und kann Licht in mein Dunkel bringen, denn mit einem Minimalbeispiel (folgt am Ende) funktioniert die Sache wie ich es mir vorstelle. Lange Rede kurzer Sinn.
Edit: OS ist Ubuntu 12.10
Fehler beim Compilieren:
Entsprechender Programmcode:
main.cpp
Scheduler.h
SchedulerFill.h
Schedulerfill.cpp
Funktionierendes Minimalbeispiel:
ich bin grade dabei auszuprobieren wie man eine Art Pluginmechanismus bewerkstelligen kann. Dazu habe ich eine abstrakte Klasse Scheduler erstellt von der dann die einzelnen "Plugins" erben und konkrete Strategien implementieren können. Damit später ohne Änderungen am Code zusätzliche Plugin benutzt werden können, sollen diese als Shared Object zur Laufzeit geladen werden. Meine Idee war also im Hauptprogramm einen Pointer vom Typ Scheduler auf die konkrete aktuell geladene Klasse zu haben. Allerdings sagt mir der Compiler, dass ich kein Objekt einer abstrakten Klasse anlegen kann, aber das versuche ich nach meinem Verständnis ja auch gar nicht. Eventuell sieht jemand von euch den Fehler und kann Licht in mein Dunkel bringen, denn mit einem Minimalbeispiel (folgt am Ende) funktioniert die Sache wie ich es mir vorstelle. Lange Rede kurzer Sinn.
Edit: OS ist Ubuntu 12.10
Fehler beim Compilieren:
Code:
main.cpp: In Funktion »int main(int, char**)«:
main.cpp:32:37: Fehler: es kann kein Objekt des abstrakten Typs »Scheduler« belegt werden
In file included from main.cpp:4:0:
Scheduler.h:6:7: Anmerkung: denn die folgenden virtuellen Funktionen sind rein innerhalb »Scheduler«:
Scheduler.h:11:22: Anmerkung: virtual std::string Scheduler::say()
make: *** [all] Fehler 1
Entsprechender Programmcode:
main.cpp
Code:
#include <iostream>
#include <dlfcn.h>
#include "Scheduler.h"
using namespace std;
int main (int argc, char* argv[]) {
void* lib = dlopen("schedFill.so", RTLD_LAZY);
if (!lib) {
cerr << "Cannot load library: " << dlerror() << '\n';
return 1;
}
// reset errors
dlerror();
create_fp* create_sched = (create_fp*) dlsym(lib, "create");
const char* dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol create: " << dlsym_error << endl;
return 1;
}
destroy_fp* destroy_sched = (destroy_fp*) dlsym(lib, "destroy");
dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol destroy: " << dlsym_error << endl;
return 1;
}
Scheduler* sched = create_sched();
sched->say();
destroy_sched(sched);
dlclose(lib);
return 0;
}
Scheduler.h
Code:
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include <iostream>
class Scheduler {
public:
Scheduler() {};
virtual ~Scheduler() {}
virtual std::string say() = 0;
};
typedef Scheduler create_fp();
typedef void destroy_fp(Scheduler*);
#endif
SchedulerFill.h
Code:
#ifndef SCHEDULERFILL_H
#define SCHEDULERFILL_H
#include "Scheduler.h"
class SchedulerFill : public Scheduler {
public:
SchedulerFill();
~SchedulerFill();
std::string say();
};
#endif
Schedulerfill.cpp
Code:
#include "SchedulerFill.h"
SchedulerFill::SchedulerFill() {}
SchedulerFill::~SchedulerFill() {}
std::string SchedulerFill::say() {
std::string test = "fill";
return test;
}
extern "C" SchedulerFill* create() {
SchedulerFill* sched = new SchedulerFill();
return sched;
}
extern "C" void destroy(Scheduler* sched) {
delete sched;
}
Funktionierendes Minimalbeispiel:
Code:
#include <iostream>
using namespace std;
class A {
public:
A() {};
virtual ~A(){}
virtual void f() = 0;
};
class B : public A {
public:
B() {}
~B() {}
void f() {
cout << "test" << endl;
}
};
int main(int argc, char** argv) {
A* test = new B();
test->f();
return 0;
}
Zuletzt bearbeitet: