Qu’est-ce qui est sûr pour un système de plug-in C ++?

Les systèmes de plug-in en C ++ sont difficiles à gérer car l’ABI n’est pas correctement défini et chaque compilateur (ou sa version) suit ses propres règles. Cependant, COM sur Windows montre qu’il est possible de créer un système de plug-in minimal qui permet aux programmeurs avec différents compilateurs de créer des plug-ins pour une application hôte à l’aide d’une interface simple.

Soyons pratiques, et laissez de côté la norme C ++, ce qui n’est pas très utile à cet égard. Si je veux écrire une application pour Windows et Mac (et éventuellement Linux) qui prend en charge les plug-ins C ++, et si je veux donner aux auteurs de plug-ins un choix assez important de compilateurs (par exemple, versions de Visual C ++ anciennes , GCC ou le compilateur C ++ d’Intel), quelles fonctionnalités de C ++ pourrais-je utiliser?

Bien sûr, je suppose que les plug-ins seraient écrits pour une plate-forme spécifique.

header, voici quelques fonctionnalités C ++ auxquelles je peux penser, avec ce que je pense être la réponse:

  • mise en page vtable, pour utiliser des objects à travers des classes abstraites? (Oui)
  • types intégrés, pointeurs? (Oui)
  • structs, syndicats? (Oui)
  • des exceptions? (non)
  • Fonctions externes “C”? (Oui)
  • stdcall non-extern “C” fonctions avec des types de parameters intégrés? (Oui)
  • non-stdcall non-extern “C” fonctions avec des types de parameters définis par l’utilisateur? (non)

J’apprécierais toute expérience que vous avez dans ce domaine que vous pourriez partager. Si vous connaissez une application à succès modéré avec un système de plug-in C ++, c’est cool aussi.

Carl

Le Journal du Dr Dobb comporte un article intitulé Construire votre propre framework de plug-in: la première partie est une très bonne lecture sur le sujet. C’est le début d’une série d’articles sur l’architecture, le développement et le déploiement d’un framework de plug-in C / C ++ multi-plateformes.

Vous pouvez également envisager de remplacer l’interface de plugin conventionnelle par une interface de script. Il existe de très bonnes liaisons pour plusieurs langages de script en C / C ++ qui ont déjà résolu votre problème. Ce ne serait peut-être pas une mauvaise idée de les développer. Par exemple, consultez Boost.Python .

Qt a un très bon système pour les plugins que j’ai utilisés par le passé. Il utilise le système de méta-objects de Qt pour résoudre de nombreux problèmes généralement rencontrés lors de la tentative de développement de plug-ins C ++.

Un exemple est comment Q_DECLARE_INTERFACE fonctionne, pour vous empêcher d’utiliser un plugin incompatible. Une autre est la clé de compilation , pour vous assurer que vous chargez le bon plug-in pour votre architecture, votre système d’exploitation, votre compilateur. Si vous n’utilisez pas le système de plug-ins de Qt, vous devrez vous soucier de ces éléments et inventer des solutions pour vous-même. Ce n’est pas nécessairement sorcier, et je ne dis pas que vous échoueriez, mais les gars de Trolltech sont assez intelligents et ont passé un bon moment à y penser, et je préfère utiliser ce qu’ils ont créé plutôt que de réinventer la roue moi-même. .

Un autre exemple est que RTTI ne fonctionne généralement pas entre les limites de la DLL, mais lorsque vous utilisez Qt, des éléments comme qobject_cast, qui reposent sur le système de méta-object, fonctionnent entre les limites de la DLL.

Je pense que vous êtes en sécurité en créant un système de plugin basé sur:

  • Empaquetage de la fonctionnalité du plugin dans la bibliothèque (.dll, .so, etc.)
  • Exiger que le plug-in expose les principales exportations en langage C.
  • Exiger que le plugin implémente (et renvoie un pointeur / référence à) une interface C ++ abstraite.

Probablement le système de plugin C ++ le plus performant: le bon vieux Adobe Photoshop . Et sinon, l’un des formats de synthé virtuel tels que VSTi etc.

Le livre Imperfect C ++ de Matthew Wilson a une belle info à ce sujet.

Le conseil semble être le suivant: tant que vous utilisez le même compilateur (ou équivalent), vous pouvez utiliser C ++, sinon vous feriez mieux d’utiliser C comme interface sur votre code C ++.

ACE a une architecture de plug-in multi-plateforme.

Check-out:

  1. ACE DLL
  2. ACE DLL Manager

Je suggère de vérifier le livre
Le guide du programmeur ACE

Firefox s’exécute sur XPCOM ( http://www.mozilla.org/projects/xpcom/ ). Il est inspiré par Microsoft COM mais il est multiplateforme.

J’ai mon propre moteur de jeu doté d’un système de plug-in C ++.

J’ai du code dans les fichiers d’en-tête afin qu’il soit mis dans l’unité de compilation du plugin.

Les fonctions plus grandes qui vivent dans le moteur principal sont appelées via une fonction C exscope (le plugin appelle MyObject_somefunction (MyObject * obj) qui dans le moteur appelle simplement obj-> somefunction ()). Si l’appel d’une fonction C est laid à votre goût, alors avec une astuce d’en-tête, lorsque l’en-tête est inclus dans le plugin, la fonction membre #defined pour appeler la fonction C:

 #if defined(IN_THE_PLUGIN) void MyObject::somefunction() { MyObject_somefunction(this); } #endif 

Les fonctions virtuelles doivent être pures ou le code réside dans le fichier d’en-tête. Si je n’hérite pas d’une classe et que je ne fais qu’installer une classe, le code de fonction virtuel peut vivre dans le moteur, mais la classe doit alors exporter certaines fonctions C pour créer et détruire l’object appelé depuis le plug-in.

Fondamentalement, les astuces que j’ai utilisées, dans le but de maintenir une indépendance totale de la plate-forme, se résument à des exportations de C et des astuces de fichiers d’en-tête.