Autor Beitrag
Mitmischer 1703
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: Di 03.04.12 11:12 
Mir ist kein besserer Begriff dafür eingefallen, deswegen habe ich es einfach mal "late late binding" genannt. Mein Problem ist folgendes:

Ich habe zwei Klassen gleichen Namens, die dasselbe Interface aber eine unterschiedliche Implementierung aufweisen und baue mir die Bibliotheken Implementation1.dll und Implementation2.dll. In einem anderen Programm möchte ich zwischen Implementation1.dll und Implementation2.dll wechseln können. Wichtig ist mir dabei, dass ich den aufrufenden Code nicht mehrmals schreiben muss:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
// Implementation1.dll
class Klasse
{
  void foo(int bar);
  int boo(void* far);
}

// Implementation2.dll
class Klasse
{
  void foo(int bar);
  int boo(void* far);
}

// aufrufender Code
void DoSomethingComplicated()
{
  // ...
  // aufrufender Code existiert nur einmal
  Klasse kl;
  kl.foo(42);
  // ...
}


Falls mein Vorhaben mit Klassen nicht möglich ist, wie sieht es mit einfachen Funktionen aus? Weiterhin soll das ganze wenn möglich auch unter Linux lauffähig sein, daher wäre es schön, wenn möglichst wenig WinAPI zum Einsatz käme.

Grüße,

Mitmischer

_________________
Die Lösung ist nicht siebzehn.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4807
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 03.04.12 11:56 
Hallo,

du programmierst in C++, oder?
Du solltest dafür dann eine abstrakte Klasse (pure virtual interface) deklarieren:
ausblenden Quelltext
1:
2:
3:
4:
5:
class Base
{
  virtual void foo(int bar) = 0;
  virtual int boo(void* far) = 0;
};

Und deine Implementationen sollten davon erben.
Dann kannst du die DLLs zur Laufzeit austauschen - bedenke jedoch, daß du dann für alle DLLs sowie den aufrufenden Code immer mit demselben Compiler kompilieren mußt (denn C++ verfügt nicht über eine genormte ABI).

P.S: Ich sehe gerade, daß du die Klasse direkt im Code instanziierst. Dies geht dann natürlich nicht mehr, d.h. am besten du definierst dir dann eine Factory-Methode, welche eine Instanz der jeweiligen Klasse (per new) erzeugt.

Ich bin mir nicht mehr sicher, aber es kann sein, daß du auch explizit den Destruktor deklarieren als auch definieren mußt (evtl. sogar direkt als erste Funktion der Klasse):
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
class Base
{
  virtual ~Base();

  // ...
};

inline Base::~Base()
{
}

(ist schon ein paar Jahre her, als ich dies das letzte mal programmiert hatte)