<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Frage zu Plugins mit abstrakten Klassen]]></title><description><![CDATA[<p>Hallo.<br />
Ist die Designidee hier gut und praktikabel, und vor allen Dingen erlaubt?</p>
<pre><code class="language-cpp">class IExtension
{
public:
    virtual const std::string &amp;GetName() const = 0;
    virtual const std::string &amp;GetDescription() const = 0;
    virtual const std::string &amp;GetVersion() const = 0;
    virtual const std::string &amp;GetDate() const = 0;
    virtual const std::string &amp;GetAuthor() const = 0;
    virtual const std::string &amp;GetEMail() const = 0;
    virtual const std::string &amp;GetURL() const = 0;
};

class IExtensionInstance : public IExtension
{
public:
    virtual bool OnLoad() = 0;
    virtual bool OnUnload() = 0;
    virtual bool OnRegisterNatives(ISystem *pSystem) = 0;
    virtual void OnExtensionLoad(IExtension *pExtension) = 0;
    virtual void OnExtensionUnload(IExtension *pExtension) = 0;
    virtual void OnAllExtensionsLoaded() = 0;
};

class IExtensionManager
{
public:
    virtual IExtension *Load(const std::string &amp;strName) = 0;
    virtual bool Unload(IExtension *pExtension) = 0;
    virtual IExtension *Get(const std::string &amp;strName) const = 0;
};
</code></pre>
<p>Meine Idee ist, wie man hoffentlich sieht, dass jede Extension auf andere Extensions zugreifen kann (momentan nur Daten abrufen), via <code>IExtension</code> . Jede Extension muss dazu natürlich alle Funktionen von <code>IExtension</code> implementieren. Außerdem werden noch einige Callbacks hinzugefügt, via <code>IExtensionInstance</code> . Funktioniert das nun auch so wie gewollt, dass ein Pluginautor gezwungen ist, alle Methoden von <code>IExtension</code> und <code>IExtensionInterface</code> zu implementieren? Und ist das legal nach dem Standard?</p>
<p>Des weiteren wollte ich Fragen, was ihr von dem Konstrukt hier haltet.</p>
<p>Edit: Noch eine Frage die mir nebenbei einfällt. Ich kenne Systeme, da gibt es solche oder ähnliche Defines zu jedem globalen Interface (so wie hier <code>IExtensionManager</code> ):</p>
<pre><code class="language-cpp">#define IFACE_EXTENSIONMANAGER &quot;ExtensionManager001&quot;
</code></pre>
<p>Ich glaube die Idee zu verstehen, nämlich dass bei einem Update der SDK die Version erhöht wird. Nur wo ist der Sinn? Dann müsste ich bei jedem Update auch die alten Versionen instanzieren, z.B. so:</p>
<pre><code class="language-cpp">class IExtensionManager001
{
public:
    virtual IExtension *Load(const std::string &amp;strName) = 0;
    virtual bool Unload(IExtension *pExtension) = 0;
    virtual IExtension *Get(const std::string &amp;strName) const = 0;
};

class IExtensionManager //002
{
public:
    virtual IExtension *Load(const std::string &amp;strName) = 0;
    virtual bool Unload(IExtension *pExtension) = 0;
    virtual IExtension *Get(const std::string &amp;strName) const = 0;
    virtual void NeueFunktion() const = 0;
};

#define IFACE_EXTENSIONAMANGER &quot;ExtensionManager002&quot;
</code></pre>
<p>Und dann in der Implementierung:</p>
<pre><code class="language-cpp">pExtensionManager = new CExtensionManager;
pExtensionManager001 = new CExtensionManager001;
</code></pre>
<p>Spätestens hier hakt es doch. Ich kann doch nicht alle alten Versionen immer neu erstellen?!</p>
<p>Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/275721/frage-zu-plugins-mit-abstrakten-klassen</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 18:00:16 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/275721.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 19 Oct 2010 21:50:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Tue, 19 Oct 2010 21:58:16 GMT]]></title><description><![CDATA[<p>Hallo.<br />
Ist die Designidee hier gut und praktikabel, und vor allen Dingen erlaubt?</p>
<pre><code class="language-cpp">class IExtension
{
public:
    virtual const std::string &amp;GetName() const = 0;
    virtual const std::string &amp;GetDescription() const = 0;
    virtual const std::string &amp;GetVersion() const = 0;
    virtual const std::string &amp;GetDate() const = 0;
    virtual const std::string &amp;GetAuthor() const = 0;
    virtual const std::string &amp;GetEMail() const = 0;
    virtual const std::string &amp;GetURL() const = 0;
};

class IExtensionInstance : public IExtension
{
public:
    virtual bool OnLoad() = 0;
    virtual bool OnUnload() = 0;
    virtual bool OnRegisterNatives(ISystem *pSystem) = 0;
    virtual void OnExtensionLoad(IExtension *pExtension) = 0;
    virtual void OnExtensionUnload(IExtension *pExtension) = 0;
    virtual void OnAllExtensionsLoaded() = 0;
};

class IExtensionManager
{
public:
    virtual IExtension *Load(const std::string &amp;strName) = 0;
    virtual bool Unload(IExtension *pExtension) = 0;
    virtual IExtension *Get(const std::string &amp;strName) const = 0;
};
</code></pre>
<p>Meine Idee ist, wie man hoffentlich sieht, dass jede Extension auf andere Extensions zugreifen kann (momentan nur Daten abrufen), via <code>IExtension</code> . Jede Extension muss dazu natürlich alle Funktionen von <code>IExtension</code> implementieren. Außerdem werden noch einige Callbacks hinzugefügt, via <code>IExtensionInstance</code> . Funktioniert das nun auch so wie gewollt, dass ein Pluginautor gezwungen ist, alle Methoden von <code>IExtension</code> und <code>IExtensionInterface</code> zu implementieren? Und ist das legal nach dem Standard?</p>
<p>Des weiteren wollte ich Fragen, was ihr von dem Konstrukt hier haltet.</p>
<p>Edit: Noch eine Frage die mir nebenbei einfällt. Ich kenne Systeme, da gibt es solche oder ähnliche Defines zu jedem globalen Interface (so wie hier <code>IExtensionManager</code> ):</p>
<pre><code class="language-cpp">#define IFACE_EXTENSIONMANAGER &quot;ExtensionManager001&quot;
</code></pre>
<p>Ich glaube die Idee zu verstehen, nämlich dass bei einem Update der SDK die Version erhöht wird. Nur wo ist der Sinn? Dann müsste ich bei jedem Update auch die alten Versionen instanzieren, z.B. so:</p>
<pre><code class="language-cpp">class IExtensionManager001
{
public:
    virtual IExtension *Load(const std::string &amp;strName) = 0;
    virtual bool Unload(IExtension *pExtension) = 0;
    virtual IExtension *Get(const std::string &amp;strName) const = 0;
};

class IExtensionManager //002
{
public:
    virtual IExtension *Load(const std::string &amp;strName) = 0;
    virtual bool Unload(IExtension *pExtension) = 0;
    virtual IExtension *Get(const std::string &amp;strName) const = 0;
    virtual void NeueFunktion() const = 0;
};

#define IFACE_EXTENSIONAMANGER &quot;ExtensionManager002&quot;
</code></pre>
<p>Und dann in der Implementierung:</p>
<pre><code class="language-cpp">pExtensionManager = new CExtensionManager;
pExtensionManager001 = new CExtensionManager001;
</code></pre>
<p>Spätestens hier hakt es doch. Ich kann doch nicht alle alten Versionen immer neu erstellen?!</p>
<p>Danke!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967778</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967778</guid><dc:creator><![CDATA[theliquidwave]]></dc:creator><pubDate>Tue, 19 Oct 2010 21:58:16 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Tue, 19 Oct 2010 22:07:10 GMT]]></title><description><![CDATA[<p>ja und ja und .... pfuh</p>
<p>erlaubt ist das alles<br />
und virtual pure funktionen müssen implementiert werden</p>
<p>bloss gibt es einige dinge bei &quot;C++ DLLs&quot; zu beachten</p>
<ol>
<li>
<p>sobald STL klassen (wie z.b. std::string) im interface verwendet werden, muss zwingend bei allen beteiligten DLLs/SOs/EXEn die selbe standard library verwendet worden sein, und normalerweise auch der selbe compiler. wobei es exakt die selbe version sein muss. unterschiedliche revisionen können funktionieren, müssen aber nicht. wenns nur ein bugfix im compiler ist ist es normalerweise kein problem. sobald die STL geändert wurde kann man nurmehr beten. bzw. sich einfach nicht drauf einlassen und zwingend vorschreiben welche STL + compiler verwendet werden müssen.</p>
</li>
<li>
<p>man muss sicherstellen dass speicher anfordern/freigeben sache zwischen den verschiedenen DLLs funktioniert. normalerweise ist das hinzubekommen, wenn man den selben compiler vorschreibt. unter windows/MSVC verwendet man dazu z.B. die DLL runtime, dann gibt es kein problem.</p>
</li>
<li>
<p>je nach compiler/system sind noch weitere dinge zu beachten. z.B. halten bei MSVC in fall von DLLs gewisse C++ &quot;versprechen&quot; nicht mehr. wie z.B. dass eine funktion für alle die selbe adresse hat, egal wo man diese adresse ermittelt. oder dass statische membervariablen von templates nur 1x pro spezialisierung vorhanden sind.</p>
</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/1967780</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967780</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 19 Oct 2010 22:07:10 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Tue, 19 Oct 2010 22:10:56 GMT]]></title><description><![CDATA[<p>zu deinem EDIT: zeich mal ein beispiel (also link auf ein konkretes ding, nicht wie du das in erinnerung hast)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967782</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967782</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 19 Oct 2010 22:10:56 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Tue, 19 Oct 2010 22:16:18 GMT]]></title><description><![CDATA[<p>Hi, danke!</p>
<ol>
<li>
<p>Das ist eine Sache, die ich noch gar nicht bedacht habe. Sch.... Was empfiehlst du? Eigene Implementierungen, oder stumpfe Benutzung von <code>char*</code> ?</p>
</li>
<li>
<p>Wie meinst du das? Zwischen dem System und den Extensions werden quasi nur Pointer und Strings ausgetauscht. Probleme mit Speicherlecks sollte es nicht geben.</p>
</li>
<li>
<p>Von beiden Versprechen habe ich noch nichts gehört, ich denke nicht dass ich diese beachten muss. Templates verwende ich eh nicht.</p>
</li>
</ol>
<p>Zum Edit: VALVe SDK für die Source Engine (hier mal ein Beispiel: <a href="http://pastebin.com/kpH4p83u" rel="nofollow">http://pastebin.com/kpH4p83u</a>)</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967785</guid><dc:creator><![CDATA[theliquidwave]]></dc:creator><pubDate>Tue, 19 Oct 2010 22:16:18 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Wed, 20 Oct 2010 00:14:06 GMT]]></title><description><![CDATA[<p>theliquidwave schrieb:</p>
<blockquote>
<p>Hi, danke!</p>
<ol>
<li>Das ist eine Sache, die ich noch gar nicht bedacht habe. Sch.... Was empfiehlst du? Eigene Implementierungen, oder stumpfe Benutzung von <code>char*</code> ?</li>
</ol>
</blockquote>
<p>Wenns geht Compiler vorschreiben. Bei MSVC geht das recht einfach (gibt ja nicht so viele Versionen), und wenn du nur Windows supporten musst, dann würde ich dir das wirklich empfehlen. Spart ne Menge Aufwand/Ärger/... BTW: Service Pack beachten!</p>
<p>Wenn das nicht geht ... Mist.</p>
<p>Im Prinzip ist nichtmal garantiert dass die ABI kompatibel ist, also dass z.B. sowas wie virtuelle Funktionen überhaupt zwischen verschiedenen Compilern funktioniert. Unter Windows normalerweise kein Problem, da ein Compiler unter Windows fast COM supporten muss, und wenn COM mit C++ (ohne Compiler-Magick) geht, dann gehen schonmal zumindest virtuelle Funktionen.<br />
Auf anderen Systemen ist u.U. gar nichts garantiert. Die Chancen stehen gut dass z.B. GCC 4.x zu GCC 4.y kompatibel ist, aber das solltest du selbst nachprüfen, ich weiss es einfach nicht.</p>
<p>Um hier sinnvoll mehr sagen zu können müsste ich etwas mehr über dein Projekt wissen. z.B. Open Source vs. Closed Source, welche Betriebssysteme sollen/müssen unterstützt werden, wie umfangreich/komplex wird das Plugin Interface werden/was für Funktionen kann man da erwarten etc.</p>
<blockquote>
<ol start="2">
<li>Wie meinst du das? Zwischen dem System und den Extensions werden quasi nur Pointer und Strings ausgetauscht. Probleme mit Speicherlecks sollte es nicht geben.</li>
</ol>
</blockquote>
<p>Es kann zu Problemen kommen wenn DLL A Speicher anfordert, und DLL B diesen wieder freigibt. Oder die EXE was anfordert und die DLL den Speicher wieder freigibt. Oder umgekehrt.<br />
Und sobald du STL Klassen verwendest, kannst du kaum noch garantieren, dass das nicht passiert.</p>
<p>Beispielsweise kann std::string intern Reference-Counting verwenden. Ist in letzter Zeit wieder aus der Mode gekommen, aber es gab und gibt vermutlich noch Implementierungen die das machen. In so einem Fall kann man schwer bis gar nicht garantieren, dass Speicher auch immer dort freigegeben wird wo er angefordert wurde.</p>
<p>Meine Empfehlung: das Problem dadurch umschiffen dass man nen genauen Compiler vorschreibt, bei dem bekannt ist, dass es kein Problem gibt.</p>
<blockquote>
<ol start="3">
<li>Von beiden Versprechen habe ich noch nichts gehört, ich denke nicht dass ich diese beachten muss. Templates verwende ich eh nicht.</li>
</ol>
</blockquote>
<p>OK. Was ich noch vergessen hatte: Exceptions über DLL Grenzen hinweg können auch problematisch sein. Wenn die DLLs von verschiedenen Compilern erstellt wurden stehen die Chancen da ganz schlecht. Wenn es (genau) der selbe Compiler ist wieder relativ gut.</p>
<p>Überhaupt kann ziemlich viel ziemlich schwierig werden wenn es NICHT der selbe Compiler in allen DLLs ist <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<blockquote>
<p>Zum Edit: VALVe SDK für die Source Engine (hier mal ein Beispiel: <a href="http://pastebin.com/kpH4p83u" rel="nofollow">http://pastebin.com/kpH4p83u</a>)</p>
</blockquote>
<p>Da kommt bei mir im Moment nur ein Error &quot;502 Bad Gateway&quot;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967798</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967798</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 20 Oct 2010 00:14:06 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Wed, 20 Oct 2010 06:53:45 GMT]]></title><description><![CDATA[<p>Zum Thema DLL's im wirklichen Leben gibts ein gutes Kapitel im Buch Imperfect C++ von Matthew Willson:<br />
<a href="https://duckduckgo.com/?q=isbn+9780321228772&amp;cppnetbooks" rel="nofollow">Imperfect C++ | ISBN: 9780321228772</a></p>
<p>Ich fands sehr gut.</p>
<p>Simon</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967835</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967835</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Wed, 20 Oct 2010 06:53:45 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Wed, 20 Oct 2010 11:16:47 GMT]]></title><description><![CDATA[<p>Hi.<br />
Danke @ hustbaer für den Roman <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ich denke, dann wird es wohl auf eine Compilervorgabe hinauslaufen. Auf Linux ist man eh an den GCC 4.3.1 gebunden, da VALVe diesen vorschreibt. Auf Windows könnte man dann noch zwischen MSVC 2008 und 2010 variieren, da muss ich mal schauen wie ich das regeln kann.</p>
<p>Im Projekt geht es darum, dass man für die Source Engine von VALVe Serverplugins nur mit C++ erstellen kann. Durch mein Plugin wird Python implementiert, so kann man also auch scripten. Nun soll es Autoren aber auch möglich sein, neue Funktionalitäten hinzuzufügen, eben durch die Extensions.</p>
<p>Das mit der Versionierung von Interfaces verstehe ich immer noch nicht. Um das SDK zu erhalten brauchst du leider ein VALVe Spiel; ein anderes SDK kenne ich bisher nicht, wo das auftaucht. Ich habe mich nämlich ein bisschen eingelesen, und dort ist mir aufgefallen, dass virtuelle Funktionen immer der Reihenfolge nach in der VTable angelegt werden. Wenn man nun UNTEN neue Funktionen hinzufügt, sollte es also keine Probleme geben, da auch alte Interfaceversionen noch immer auf die richtigen Stellen zugreifen. Sie haben eben nur keine Chance auf neue Funktionen zuzugreifen.</p>
<p>@ theta: Mal schauen. Ich denke aber nicht, dass ich mir extra dafür ein Buch kaufen werden. Trotzdem danke <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967944</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967944</guid><dc:creator><![CDATA[theliquidwave]]></dc:creator><pubDate>Wed, 20 Oct 2010 11:16:47 GMT</pubDate></item><item><title><![CDATA[Reply to Frage zu Plugins mit abstrakten Klassen on Wed, 20 Oct 2010 11:52:59 GMT]]></title><description><![CDATA[<p>theliquidwave schrieb:</p>
<blockquote>
<ol>
<li>Das ist eine Sache, die ich noch gar nicht bedacht habe. Sch.... Was empfiehlst du? Eigene Implementierungen, oder stumpfe Benutzung von <code>char*</code> ?</li>
</ol>
</blockquote>
<p>Wenn dann const char*. Eine Referenz auf std::string als return einer pure-virtual-Funktion würd ich auch nicht machen, da dadurch jedes Plugin für jede Funktion einen std::string speichern muss, wenn auch nur als static in der jeweiligen Funktion.<br />
In deinem Fall verlierst du eigentlich nichts, wenn die Funktionen const char* zurückgeben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1967968</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1967968</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Wed, 20 Oct 2010 11:52:59 GMT</pubDate></item></channel></rss>