Question

Je l'ai mis en place un "système de plug-in" très basique dans le cadre d'une bibliothèque statique . Chaque « plug-in » implémente le support pour un format d'image spécifique, par exemple GIF, JPEG, etc .. De plus, j'ai un Singleton (une classe appelée PluginManager) qui maintient une liste de tous les plug-ins disponibles.

La partie la plus délicate est que je veux désactiver / activer les plug-ins en ajoutant ou en supprimant les fichiers sources à partir du fichier de projet. Pour y parvenir, chaque plug-in crée une variable globale (avec des noms différents) et enregistre le plug-in dans le constructeur de cette classe à jpeg_instance.

Quelque chose comme ça pour le format JPEG ...

struct JPEGPlugin
{
  // constructor will register plugin
  JPEGPlugin()
  {
    PluginManager::Singleton().RegisterPlugin(this);
  }

  // plenty of other code
  ...
};

JPEGPlugin jpeg_instance;  // instantiate in global scope

Cependant, bien que cela fonctionne parfaitement en théorie, il échoue en liant cette bibliothèque statique à un autre code pour construire un exécutable. Tant que cet exécutable ne voit pas l'accès aux plug-ins (comme GLOBALS <=>), l'éditeur de liens n'a pas une connexion (il ignore complètement les effets secondaires du constructeur) et ne comprend pas le code dans l'exécutable final. En d'autres termes, le plug-in JPEG n'est pas disponible dans l'application finale.

Je suis tombé sur les problèmes deux ou trois fois au fil des ans, et j'ai toujours cherché sur le net des solutions. A chaque fois, je viens de trouver les pages qui disent essentiellement que c'est un problème connu et que je dois vivre avec.

Mais peut-être quelqu'un sait alors comment faire ce travail?

Était-ce utile?

La solution

Je ne sais pas si cette solution pour la façon dont vous avez résolu ce problème, mais nous avons eu un problème similaire avec l'enregistrement statique d'une usine d'objet et dans Visual Studio nous résolu en déclarant les classes concernées par __declspec (dllexport) cela était nécessaire, même si les bibliothèques ne sont pas impliquées dll. Mais sans que cela l'éditeur de liens omettrait les classes non référencées.

La solution de registre, nous avons travaillé un peu différent et ne comportaient pas d'objets de pile alloué. Je soulevai pièces de-unité du RPC, qui est aussi où je découvre l'approche __declspec IIRC.

[modifier] Nous avons également la déclaration de #include la classe enregistrée de quelque partie du code.

Autres conseils

Comme il est un libary statique, vous pourriez envisager d'avoir le gestionnaire enregistrer les plug-ins (au lieu des plug-ins eux-mêmes l'inscription). Le fichier d'en-tête peut définir un symbole preproc (c.-à-JPEG_PLUGIN) qui contrôle si le gestionnaire enregistre ou non le plug-in basé sur l'inclusion de l'en-tête:

#include "JpegPlugin.h"

void PluginManager::RegisterPlugins()
{
#idef JPEG_PLUGIN
    RegisterPlugin(&jpeg_instance);
#endif
}

JpegPlugin.h ne doit pas nécessairement inclure la définition du JpegPlugin. Il pourrait être quelque chose comme ceci:

#ifndef JPEG_PLUGIN_HEADER
#define JPEG_PLUGIN_HEADER

#if 0 // change this to 1 to use the plugin
#define JPEG_PLUGIN
#include "Jpeg_PluginCls.h"
#endif

#endif

Il est suivi réponse Harald Scheirich .

Je l'ai fait quelques expériences, et il semble que le mode de sortie de MSVC ++ 2005 (mais pas en mode débogage) allume le /OPT:REF drapeau à l'éditeur de liens, qui, selon le LINK documentation , provoquera des symboles non référencés à retirer de l'EXE final. Et, la page web pour semble __declspec(selectany) indiquer que les constructeurs pour objets globaux ne sont pas considérés comme étant des références à un objet (à tort à mon humble avis, mais vous l'avez). Donc, je suppose que ce problème « disparaît » pour debug - est-ce pas

Alors, je pense que la suggestion de Harald d'utiliser est un moyen __declspec(dllexport) pratique de marquer le symbole comme « référence », car il est spécifié dans le code source. Si pour une raison quelconque, vous vouliez éviter d'exporter le symbole, je suppose que vous pouvez accomplir la même chose en utilisant soit le /INCLUDE:mysymbol éditeur de liens drapeau , ou d'éteindre le drapeau <=>.

S'il vous plaît:

  1. ajouter le projet lib statique comme référence au projet exe
  2. définir à la fois des « dépendances de bibliothèque de liens » et « Utiliser la dépendance de bibliothèque de liens comme entrées » comme vrai.

Voir ceci: config

Lorsque la « dépendance de bibliothèque de liens d'utilisation comme entrées » est réglé sur Oui, les liens du système de projet dans les fichiers OBJ pour .libs produits par les projets dépendants. Donc, tous les symboles sont keeped.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top