Je me demandais comment partager une certaine mémoire entre différents modules de programme - disons, j'ai une application principale (EXE), puis un module (DLL). Ils sont tous deux liés à la même bibliothèque statique. Cette bibliothèque statique aura un gestionnaire, qui fournit divers services. Ce que je voudrais réaliser, c'est que ce manager soit partagé entre tous les modules d'application et pour ce faire de manière transparente lors de l'initialisation de la bibliothèque. Entre les processus, je pourrais utiliser une mémoire partagée, mais je veux que cela soit partagé dans le processus en cours. Pourriez-vous penser à une manière inter-plate-forme de faire cela? Éventuellement utiliser des bibliothèques de boost, s'ils fournissent des installations pour le faire. P>
Seule une solution que je puisse penser en ce moment, est d'utiliser la bibliothèque partagée du système d'exploitation respectif, que tous les autres modules relieront au moment de l'exécution et que le gestionnaire a été enregistré là-bas. P>
EDIT: Pour clarifier ce que j'ai réellement besoin: p>
4 Réponses :
Vous pouvez utiliser boost :: interprocess code> http://www.boost.org/doc/libs/1_45_0/doc/html/interprocess.html
Et sous Windows, vous pouvez créer un segment partagé dans votre DLL qui sera partagé par tous les processus à l'aide de # Pragma's: http://www.codeproject.com/kb/dll/data_seg_share.aspx p>
Oui, j'espère que cela peut être résolu avec boost, mais pourriez-vous être plus spécifique comment créer un segment de mémoire nommé dans le processus actuel uniquement?
Qu'entendez-vous par "processus actuel seulement?" Accessible d'un processus seulement? Entreprise d'un processus seulement?
Si je crée une mémoire partagée avec une pièce d'identité, elle sera accessible à partir de tous les processus du système, non? J'ai besoin que la mémoire ne soit accessible que par le processus qui le crée, avec un accès complet en lecture / écriture
Je ne comprends pas. Pourquoi avez-vous besoin de la mémoire partagée du tout, si vous avez tout dans un processus? La mémoire est déjà accessible à chaque fonction de ce processus et est déjà isolée d'autres processus.
Oui, la mémoire est accessible, mais comment trouver l'adresse, où réside mon objet manager hypothétique? Je ne peux pas utiliser la variable globale, car nous parlons de différents modules de programme, qui sont compilés séparément.
Appelez une fonction exportée de ce module pour l'obtenir
Pour une utilisation à partir du processus en cours uniquement, vous n'avez pas besoin de concevoir une fonction ou une structure spéciale.
Vous pouvez le faire même sans aucune fonction, mais c'est plus sûr et une plate-forme croise conviviale pour définir l'ensemble des fonctions fournissant accès aux données partagées. Et ces fonctions pourraient être mises en œuvre par la bibliothèque statique commune. P>
Je pense que cette configuration est que: "Qui va posséder les données?". Il doit exister un seul et un seul propriétaire des données partagées. P>
avec ces idées de base, nous avons pu esquisser l'API comme ceci: p> ou c ++ La classe avec le modèle singleton sera appropriée. p> update strong> p> J'ai été confus. Un vrai problème peut être défini comme "Comment implémenter une classe Singleton dans une bibliothèque statique qui sera liée à plusieurs bibliothèques de chargement dynamique (sera utilisée dans le même processus) de la plate-forme de manière indépendante". P> Je pense , la base de base n'est pas très différente mais assurez-vous que le singleton est le seul single est le problème supplémentaire de cette configuration. P> À cette fin, vous pouvez utiliser Boost.InterProcess. P>
#include <boost/config.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
...
boost::interprocess::named_mutex* singleton_check = 0;
// in the Create function of the singleton
try {
singleton_check = new boost::interprocess::named_mutex(boost::interprocess::create_only, "name_of_the_mutex" );
// if no exception throw, this is the first time execution
}
catch (...)
{
}
La façon dont j'allais aborder cela, c'était de vérifier la mémoire nommée - si elle existait déjà, je voudrais y accéder et faire un travail dont j'ai besoin, et si cela n'existait pas, je le créerais. Il en va de même pour la désinitialisation - chaque module enregistrerait, pour suivre le nombre d'utilisations et le dernier fermé effectuera le nettoyage.
Si sa chose intervenante vous avez besoin de fonctionnalités spéciales fournies dans la plate-forme. Mais si son "à l'intérieur du processus actuel", des variables définies dans le monde sont la mémoire nommée.
Une variables globales ne serait-elle pas uniquement partagée dans un seul module, avec les copies séparées d'autres modules?
Eh bien, votre édition me permettra de vérifier, si c'est la première fois que j'essaie d'accéder à / créer le singleton, mais comment puis-je stocker l'instance créée de l'objet Singleton?
@John vous avez raison. Si nous ne pouvons pas nous assurer que le singleton est vraiment célibataire, nous ne pouvons également pas accéder à l'instance Singleton. Nous pouvons surmonter ce problème en introduisant une mémoire partagée inter-processus ou quelque chose. Mais je pense que c'est vraiment trop excitée d'aller aussi loin.
# update2: la fourniture de 2 versions de la bibliothèque statique ne serait pas un problème - la seule exigence est, elles fournissent tous deux la même fonctionnalité de base, mais le serveur on pourrait en fournir d'autres, ou au moins cela peut effectuer plus d'actions à l'arrière-plan. (initialisation). J'ai prévu d'utiliser au moins 2 versions de la Statique Libs - une pour l'exécutable et de la seconde pour les bibliothèques partagées, mais je ne sais plus que si cela serait possible, en raison de l'ordre de l'initialisation du programme (voir mon Commentaire sur Ben Voigts Répondre).
Je pense que vous allez avoir besoin d'aide d'une bibliothèque partagée pour le faire de manière portable. Il n'a pas nécessairement besoin de savoir quoi que ce soit sur les objets partagés entre les modules, il doit simplement fournir un mappage accessible à l'échelle mondiale d'une clé (probablement une chaîne) à un pointeur. P>
Toutefois, si vous êtes prêt à appeler OS API, cela est réalisable, et je pense que vous n'avez peut-être pas besoin de deux implémentations de la pièce spécifique au système d'exploitation (une pour les DLLS Windows et GetProcAddress, une pour les OSES qui utilisent Dlopen). p>
Comme chaque module se charge, il marche la liste des modules précédemment chargés à la recherche de tout ce qui exportait une fonction spécialement nommée. S'il en trouve un (tout, peu importe qui, parce que l'invariant est que tous les modules entièrement chargés sont conscients de l'objet commun), il reçoit l'adresse de l'objet commun du module précédemment chargé, puis incrémente le nombre de références . S'il est incapable de trouver, il attribue de nouvelles données et initialise le nombre de références. Pendant le déchargement du module, il décrémente le nombre de références et libère l'objet commun si le nombre de références atteint zéro. P>
Bien sûr, il est nécessaire d'utiliser l'allocator du système d'exploitation pour l'objet commun, car bien que peu probable, il est possible qu'il soit traité d'une bibliothèque différente de celle qui l'a chargé d'abord. Cela implique également que l'objet commun ne peut contenir aucune fonction virtuelle ni autre type de pointeur sur des segments des différents modules. Toutes ses ressources doivent être allouées de manière dynamique à l'aide de l'allocateur à l'échelle du processus d'exploitation. C'est probablement moins d'un fardeau sur les systèmes où libc ++ est une bibliothèque partagée, mais vous avez dit que vous liez statiquement le CRT. P>
fonctions nécessaires dans Win32 inclurait Tout considéré, je pense que je voudrais coller l'objet commun dans sa propre bibliothèque partagée, qui exploite les structures de données du chargeur pour le trouver. Sinon, vous réinventez le chargeur. Cela fonctionnera même lorsque le CRT est statiquement lié à plusieurs modules, mais je pense que vous vous préparez pour les violations ODR. Être vraiment particulier pour garder la podage de données commune. P> énumprocessmodules code>,
getprocAdress code>,
heaphoc code>, et
heapfree code>,
getProcessheap code> et
getcurrentProcess code>. p>
Eh bien, c'est une solution vraiment créative :-) Je me demande, si la demande exécutable des liens vers certaines bibliothèques partagées (automatiquement au démarrage) et que certaines variables globales définies sont l'ordre de chargement des bibliothèques / initialisation des variables globales défini par la norme, ou est-ce que la mise en œuvre est définie? Si les données globales sont initialisées en premier, nous pouvons effectuer l'initialisation dans l'exécutable principal et ne vous inquiétez pas des différents allocateurs de MEM en cas de liaison de CRT statique.
@John: Oh, vous garantissez-vous que ces variables existent dans l'exécutable principal? Je pensais que vous conceviez pour l'affaire Général: essayer de construire une bibliothèque qui fonctionne si l'application utilise le même objet d'assistance ou non. Quoi qu'il en soit, les bibliothèques ne sont pas traitées par la norme C ++, de manière spécifique, l'ordre de chargement n'est donc pas défini par la norme. Cependant, sur la plupart des bibliothèques de plates-formes sont gérées par le chargeur OS avant que tous les constructeurs ne fonctionnent. Bien entendu avec la charge tardive ou le chargement explicite, les bibliothèques ne se chargent pas pendant le démarrage, mais lorsque ce code s'exécute.
Oui, la bibliothèque est censée être générique, donc c'était juste une pensée.
Selon MSDN i Voir Il n'y a que deux façons de partager des données entre les modules p>
Lorsque quelqu'un a souligné que le segment partagé ne fonctionne que pour deux instances de la même dll afin que nous ne restions qu'un seul choix pour utiliser la technique des fichiers mappés de mémoire. p>
Étant donné qu'il s'agit d'un processus unique, comment est-ce différent d'un modèle singleton normal?
C'est en fait un singleton, problème est de savoir comment la mettre en œuvre, il sera donc partagé entre différentes bibliothèques partagées.
Dans le même processus, tout module peut accéder aux variables globales externes sans aucune restriction.
Même si elles sont définies dans les bibliothèques statiques, que les partagées sont liées à? J'imagine que cela puisse travailler, si j'utilise les bibliothèques dynamiques d'exécution, mais le fait est, j'ai besoin de cela pour travailler même si j'utilise le CRT statique.