P
Mir fallen spontan zwei Möglichkeiten ein:
A)
Du schreibst Ableitungen von I1, I2, I3, nennen wir sie mal J1, J2, J3, die einen Pointer/eine Referenz auf deinen Pluginkern haben (den der die Mutliplikation macht), und die die verschieden benannten Funktionsaufrufe der Interfaces in die Aufrufe des Pluginkerns übersetzt. Für die Rückaufrufe leiten J1, J2, J3 außerdem von einer gemeinsamen Basisklasse ab (JBase), in der die möglichen Rückaufrufe pur virtuell deklariert sind. J1, J2, J3 implementieren sie in entsprechende Aufrufe an den jeweiligen Host. Der Pluginkern hält einen Pointer auf JBase (hinter dem dann in Wirklichkeit ein entsprechender J1, etc. sitzt) über den er die Rückaufrufe triggern kann.
Bei Möglichkeit A sind also die Methoden in den Jx so gut wie alle virtuell, die vom Pluginkern nicht.
Die Jx leiten nur von den Ix ab, haben aber außerdem in den meisten Fällen Funktionen für die Rückaufrufe, die in allen Jx gleich aufgerufen werden können. Der Pluginkern ist ein Klasentemplate das von einer Basisklasse erbt. Der Templateparameter ist jeweils eine Jx-Klasse. Jx halten einen Pointer auf die Basisklasse, der jeweilige Pluginkern hält einen Pointer auf sein Jx. In dem Fall wird der Kern über das Basisklasseninterface aufgerufen, die Rückaufrufe geschehen über die Jx-Methoden - da es sich um Templateargumente handelt müssen die Jx nicht in der gleichen Klassenhierarchie sein (statische Polymorphie). Der Vorteil gegen Ansatz A ist, dass man den Kern im Notfall für bestimmte Hosts (bzw. für die entsprechenden Jx) spezialisieren kann. Der Nachteil ist, dass die Methoden der Pluginkerne virtuell sind.