FirebirdSQL logo

Constructeur de plugins

Une autre interface requise pour que le plugin fonctionne est IPluginFactory. La class instancie le plugin et le renvoie au gestionnaire de plugins. La class ressemble généralement à ceci :

class Factory : public IPluginFactoryImpl<Factory, CheckStatusWrapper>
{
public:
  IPluginBase* createPlugin(CheckStatusWrapper* status,
                            IPluginConfig* factoryParameter)
  {
    MyPlugin* p = new MyPlugin(factoryParameter);
    p->addRef();
    return p;
  }
};

Il faut faire attention au fait que même dans le cas où le code de la fonction peut lever des exceptions (le nouvel opérateur peut lever une exception lorsque la mémoire est épuisée), vous n’avez pas toujours besoin de définir manuellement le bloc try/catch - l’implémentation des interfaces Firebird fait le travail pour vous, dans l’implémentation IPluginFactory ce traitement a lieu dans le modèle IPluginFactoryImpl. Notez que les shims d’état par défaut ne gèrent que l’exception FbException. Mais si vous travaillez sur un grand projet, définissez votre propre wrapper, auquel cas vous pouvez gérer n’importe quel type d’exception C++ et transmettre des informations utiles à ce sujet à partir de votre plugin.

Point d’initialisation du module Plugin

Lorsque le gestionnaire de plugins charge un module de plugin, il appelle la routine d’initialisation du module, qui est la seule fonction FB_PLUGIN_ENTRY_POINT du plugin exportée. Pour écrire le code, il aura besoin de deux variables globales : le module de plugin et la constructeur de plugins. Dans notre cas, il s’agit de :

PluginModule module;

Factory factory;

Si un module contient plus d’un plugin, vous aurez besoin d’un constructeur pour chaque plugin.

Pour FB_PLUGIN_ENTRY_POINT il ne faut pas oublier qu’il doit être exporté depuis le module plugin, cela nécessite de prendre en compte certaines caractéristiques du système d’exploitation. Pour ce faire, nous utilisons la macro FB_DLL_EXPORT définie dans examples/interfaces/ifaceExamples.h. Si vous êtes sûr que vous n’utilisez le plugin que pour un système d’exploitation spécifique, vous pouvez rendre cet endroit un peu plus facile. Au minimum, la fonction doit enregistrer le module et toutes les constructeurs dans le gestionnaire de plugins :

extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master)
{
  IPluginManager* pluginManager = master->getPluginManager();
  module.registerMe(pluginManager);
  pluginManager->registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
                                       "fbSampleDbCrypt",
                                       &factory);
}

Tout d’abord, nous appelons la fonction récemment écrite PluginModule::registerMe(), qui enregistre le IPluginManager pour une utilisation ultérieure et enregistre notre module de plugin. Enregistrez ensuite la class (ou les class s’il y aura plusieurs plugins dans un module). Nous devons passer le bon type de plugin (les types valides sont listés dans l’interface IPluginManager) et le nom sous lequel le plugin sera enregistré. Dans le cas le plus simple, il devrait être le même que le nom de la bibliothèque dynamique du plugin. Cette règle vous aidera à ne pas configurer le plugin manuellement dans plugins.conf.

Notez que contrairement aux applications, les plugins n’ont pas besoin d’utiliser fb_get_master_interface() pour obtenir iMaster. Au lieu de cela, vous devez utiliser l’instance passée à FB_PLUGIN_ENTRY_POINT. Si vous avez besoin d’une interface iMaster dans votre plugin, assurez-vous de la conserver dans cette fonctionnalité.