Partage
  • Partager sur Facebook
  • Partager sur Twitter

Partager des variables statiques.

Comment partager des variables statique entre l'application et un .so.

Sujet résolu
    10 janvier 2021 à 22:57:52

    Salut alors j'utilise un .so plutôt que un .dll pour que ça soit compatible avec linux.

    template<typename R, typename... A>
                R run(std::string fName, A... a) {
                    std::string path = "./"+funcName+".so";
                    
                    if (!isDllOpened) {
                        flib = dlopen(path.c_str(), RTLD_LAZY);
                        if (!flib) {
                            throw Erreur(10, "Failed to open dynamic library!", 3);
                        }
                        isDllOpened = true;
                    }
                    typedef R(*func)(A...);
                    func pfunc = (func) dlsym(flib, fName.c_str());
                    if (!pfunc) {
                        throw Erreur(10, "Failed to load the function!", 3);
                    }
    
                    return pfunc(a...);
                }

    Ca appelle bien la function dans le .so mais le problème c'est que je voudrais partagé des variables statiques entre le .so, et l'application, j'ai donc ajouté ceci dans le fichier .cpp ou j'initialise ma variable statique :

    #pragma data_seg (globdata)
            std::vector<window::IEvent> Command::events = std::vector<window::IEvent> ();
            #pragma data_seg()
    #pragma COMMENT (linker, "/SECTION:SHARED,RWS")

    Et j'ai ajouté ceci dans le .def :

    SEGMENTS
    globdata CLASS 'DATA' SHARED

    Comme expliqué dans ce lien : https://caligari.dartmouth.edu/doc/ibmcxx/en_US/doc/language/ref/rnpgdtsg.htm

    Le problème c'est que ça ne fonctionne pas ça me crée deux fois la variable statique au lieu de la partager, est ce parce que c'est un .so et pas un .dll ?

    Est t'il possible de faire ça sous linux ? 

    J'utilise mingw.


    EDIT : j'ai essayé ça 

    #ifdef __GNUC__
            std::vector<window::IEvent> Command::events __attribute__((section ("globdata"), shared)) = std::vector<window::IEvent> ();
            #endif // __GNUC__

    Mais ça ne marche pas non plus!

    EDIT 2 : j'ai lu que ce n'était possible que sur windows avec un .dll j'ai donc chargé un .dll

    template<typename R, typename... A>
                R run(std::string fName, A... a) {
                    std::string path = "./"+funcName+".dll";
                    if (!isDllOpened) {
                        flib = LoadLibrary(path.c_str());
                        if (!flib) {
                            throw Erreur(10, "Failed to open dynamic library!", 3);
                        }
                        isDllOpened = true;
                    }
                    typedef R(*func)(A...);
                    func pfunc = (func) GetProcAddress(flib, fName.c_str());
                    /*if (!isDllOpened) {
                        flib = dlopen(path.c_str(), RTLD_LAZY);
                        if (!flib) {
                            throw Erreur(10, "Failed to open dynamic library!", 3);
                        }
                        isDllOpened = true;
                    }
                    typedef R(*func)(A...);
                    func pfunc = (func) dlsym(flib, fName.c_str());*/
                    if (!pfunc) {
                        throw Erreur(10, "Failed to load the function!", 3);
                    }
    
                    return pfunc(a...);
                }

    Mais ça ne marche pas la variable statique n'est toujours pas partagée!!!


    -
    Edité par OmbreNoire 10 janvier 2021 à 23:45:16

    • Partager sur Facebook
    • Partager sur Twitter
      11 janvier 2021 à 0:21:13

      Et si tu remplaçais tes cochonneries de variables statiques par des variables pas statiques ?

      Les variables statiques sont des défauts de design.
      Là, avec tes bidouilles de partage de statiques, tu rajoutes de la merde sur un truc qui sent déjà pas bon.

      • Partager sur Facebook
      • Partager sur Twitter

      Si vous ne trouvez plus rien, cherchez autre chose.

        11 janvier 2021 à 15:34:18

        Parfois il est indispensable d'avoir une variable statique comme celle qui compte le nombre d'entités créées par exemple, je crois que ça ne marche pas car je compile ODFAEG en static, je dois compiler ODFAEG en shared.

        Le problème c'est que, je ne peux pas la compiler en shared car odfaeg-core dépend de odfaeg-graphics et odfaeg-graphics depend de odfaeg-core.

        Et je ne peux pas partager une variable statique avec une librarie statique.

        Vive le c++!!!

        -
        Edité par OmbreNoire 11 janvier 2021 à 15:44:53

        • Partager sur Facebook
        • Partager sur Twitter
          11 janvier 2021 à 15:57:48

          OmbreNoire a écrit:

          Parfois il est indispensable d'avoir une variable statique comme celle qui compte le nombre d'entités créées par exemple

          Et si tu as une classe mère, que tu instancies qu'une seule fois, et c'est elle qui est chargée de créer tes objets. Et dans ses membres, elle a le compteur dont tu parles ? Ainsi, plus de variable static :)
          • Partager sur Facebook
          • Partager sur Twitter

          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

            11 janvier 2021 à 16:05:26

            Ok, je vais éliminer toutes les variables statiques, de toute façon, je ne n'ai pas le choix car je ne peux pas les partager entre l'application et la dll car je ne peux pas compiler ODFAEG en shared à cause de modules interdépendants.
            • Partager sur Facebook
            • Partager sur Twitter
              11 janvier 2021 à 16:12:12

              >Parfois il est indispensable d'avoir une variable statique

              NON, c'est jamais indispensable.

              Pas que c'est inutile mais il y a toujours plusieurs manière de faire une chose et une variable statique n'est qu'un moyen, et c'est rarement le meilleur.

              >comme celle qui compte le nombre d'entités créées par exemple,

              Exercice "d'école" qui n'a aucun intérêt pratique et qui a bon nombre d'implémentation de plus haut niveau d'abstraction bien mieux implémenté qu'une variable statique caché dans un coin sombre. (Singletons de comptage (et encore, c'est un peu pourri), gestionnaires de pool d'instance, services de comptage pour statistique : compteur de performance, etc...)

              @OmbreNoire, t'es à la rue niveau conception, et tant que tu n'en auras pas conscience, tu ne progresseras pas.

              >je crois que ça ne marche pas car je compile ODFAEG en static, je dois compiler ODFAEG en shared.

              Qu'est que c'est que ce nouveau bouc émissaire sorti de ton chapeau ? (BORDEL !!!, quand c'est pas un bug du compilateur, c'est une limitation fomentée par les Illuminati-Reptiliens)

              Primo, est-on sûr que LA variable statique est la bonne solution au problème initial. Moi, j'en doute, mais comme tu ne nous expliques pas ton problème initial, on ne peut juger sur pièce, et mes a priories négatifs issus de tes "argumentaires" précédents font que je pense fortement à un mésusage du bidule.

              Secondo, même sans le support du linker, réserver une plage mémoire dans l'espace d'adressage d'un exécutable et faire en sorte d'avoir un lien entre cette zone et une ".so" chargée dynamiquement, ça doit représenter quelques lignes à quelques dizaines de lignes dans l'application et dans les greffons, pas plus. Si le Design Pattern est le bon, c'est surement pas un putatif manque dans le linker qui justifierai son abandon.

              Tertio, c'est personnel, mais faire un partage d'objet, en sachant que le compilateur de l'application et du ".so" ne seront peut-être pas les mêmes, c'est vraiment chercher les emmerdes pour une solution qui ne fonctionnera pas correctement ailleurs que dans des programmes "jouets". Donc pourquoi ne pas utiliser des types à l'ABI maîtrisable ?

              P.S.: On peut pas dire que tu es pusillanime dans tes recherches mais faut quand même canaliser toute cette énergie sur de bonnes méthodes d'analyse et résolution de problème et pas faire arbitrairement des hypothèses totalement foireuses.

              EDIT :

              >je ne peux pas la compiler en shared car odfaeg-core dépend de odfaeg-graphics et odfaeg-graphics depend de odfaeg-core.

              Et ça te choc pas ?

              Le b.a-ba de l'analyse, il faut faire sauter cette dépendance circulaire, ASAP.

              Je ne connais pas ce "odfaeg", mais un "core" n'a pas à dépendre d'un sous-module, ou il porte mal son nom, donc il faudrait le renommer fissa. Faites en sorte que "odfaeg-core" ne dépende d'aucun module "de plus haut niveau", C'EST LA PRIORITÉ.

              Le fait que c'est "compilable" (et il faut le dire vite) en "static", c'est du "bug exploit". Votre machin ne compile pas, tout compte fait.

              Si votre projet n'est pas compilable dans une usine de build, c'est qu'il n'est pas compilable.

              -
              Edité par bacelar 11 janvier 2021 à 16:22:04

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                11 janvier 2021 à 18:10:32

                Comment fait on une classe mère que l'on n'instancie qu'une seule fois ? Un singleton ? Mais un singleton contient une variable statique non ?

                Bref je ne vois qu'un seul moyen de faire c'est en utilisant une factory.

                • Partager sur Facebook
                • Partager sur Twitter
                  11 janvier 2021 à 18:33:55

                  Std::cout c'est une variable statique qui sert à rien ? :-)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 janvier 2021 à 19:15:07

                    Commence pas briser les cycles de tes modules, ou refactorise ton découpage en modules/".so".

                    >Mais un singleton contient une variable statique non ?

                    A bon ? L'une des implémentations les plus bateau (non thread-safe) d'un Singleton est l'utilisation d'une variable locale statique. Alors, si tu confonds variables statiques (globales) et variables locales statiques, on n'est pas arrivé.

                    Et pour ce qui est de l'implémentation d'une variable locale statique, c'est le compilateur qui choisit comment il l'implémente, en fonction des possibilités offertes par l'OS ou l'architecture machine. Et si le compilateur les gèrent comme des variables statiques globales, ce n'est que fortuitement (car les contraintes d'initialisation ne sont pas les mêmes).

                    >Bref je ne vois qu'un seul moyen de faire c'est en utilisant une factory.

                    Ca commence à être lassant ta sale habitude de "c'est le seul moyen". Putain d'appel à l'ignorance, NON, CE N'EST PAS LE SEUL MOYEN, BORDEL !!!

                    En plus, tu n'indiques pas le problème initial parce que tu te bloques sur des "solutions" trouvées par des raisonnements complètement erronés.

                    Si les méthodes à base de "__attribute__" de GCC ne fonctionnaient pas, t’inquiètes que ça serait réparé ou retiré depuis bien longtemps. Si ça ne "marche" pas, le problème est entre la chaise et le clavier, encore une fois.

                    Je ne dis pas que c'est facile à utiliser mais faut quand même pas passer d'une "solution" à une autre sans rien comprendre à ce que l'on fait, sinon, on se prend un mur, ou une "solution" toute pourrie.

                    Le problème que j'entrevois via les différentes questions (et en espérant ne pas faire d'amalgame avec d'autres PO), c'est une architecture à base de greffon avec rechargement de à chaud tout en gardant les anciennes données, avec possibilité de fournir un code C++ en guise de scripting d'objet (idée que je trouve totalement ridicule, mais comme l'idée de "l'architecture" de Minecraft qui s'est vendu 2 Milliards de $).

                    Si c'est le cas, je ne comprends pas pourquoi vous voulez que des données restent en mémoire entre le déchargement et le rechargement du greffon. Pourquoi ne pas sauvegarder ces données au déchargement du greffon et les rechercher au moment du rechargement du greffon ?

                    Si c'est "vraiment" nécessaire, pourquoi ne pas implémenter un allocateur mémoire dans l'application, à base d'une table associative, appelable depuis les greffons et qui gérera des chunks de mémoire, opaque pour l'application, avec des clés de la table correspondant à un "identifiant" du greffon (sous Windows, il ne peut avoir qu'une Dll avec un nom fichier donné, chargé dans un exécutable ; dans ce cas, le nom du fichier contenant le greffon peut donc servir de clé).

                    En résumé, corrige "ODFAEG", puis prend le temps d'analyser le problème, avant de pondre une solution à la con.

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                      12 janvier 2021 à 0:20:52

                      Bon j'ai déjà changé certains fichiers de modules pour éliminer les modules inter-dépendant, cependant, je n'arrive toujours pas à compiler ma lib en shared...
                      • Partager sur Facebook
                      • Partager sur Twitter
                        12 janvier 2021 à 7:26:47

                        Faut changer certaines options dans certaines commandes.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 janvier 2021 à 9:32:25

                          Créer une bibliothèque partagée n'est pas normée par POSIX (un point négatif comparé aux bibliothèques statique). Chaque plateforme a sa manière. Sous linux c'est cc -shared, sous mac cc -dynamiclib et sous Windows cela dépend entre MinGW/VS.

                          Utiliser CMake permet de s'affranchir de cette tâche fastidieuse si tu ne souhaites pas perdre de temps.

                          Note aussi: dlopen et ses amies sont des fonctions POSIX et ne sont pas disponibles sous Windows. Il faudra rajouter une prothèse d'émulation si tu souhaite utiliser cette interface.

                          -
                          Edité par markand 12 janvier 2021 à 9:35:18

                          • Partager sur Facebook
                          • Partager sur Twitter

                          git is great because Linus did it, mercurial is better because he didn't.

                          Partager des variables statiques.

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown