Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction statique pas appelée.

Lorsque j'appelle une fonction d'un .so

Sujet résolu
    9 janvier 2021 à 1:05:44

    Salut, voici le code de la fonction que j'appelle dans le .so : 

    void readObjects (ODFAEGCreator *c) {
       EXPORT_CLASS_GUID(EntityPnj,odfaeg::graphic::Entity,sorrok::Pnj)
       std::ifstream ifPnj ("Pnj.oc");
       odfaeg::core::ITextArchive iaPnj (ifPnj);
       iaPnj(vPnj);
       #ifdef ENTITYquesty
           for (unsigned int i = 0; i < vPnj.size(); i++)
               c->addExternalEntity(vPnj[i]);
           c->updateNb("Pnj",vPnj.size());
       #endif
    }

    Je passe à la fonction un pointeur sur l'application courante lorsque je l'appelle : 

    if (file) {
                    rtc.addSourceFile("sourceCode");
                    rtc.compile();
                    rtc.run<void>("readObjects", this);
                }

    Pour tester j'ai déclaré une variable statique que je met à jour ici : 

    Command::sname = "EXTERNAL";
        entity->setExternal(true);
        selectedObject=entity;
        displayTransformInfos(entity);
        displayEntityInfos(entity);
        World::addEntity(entity);

    Mais on dirait que lorsque j'appelle la fonction à partir d'un .so, ce n'est pas la même fonction statique de la classe Command qui est appelée que celle qui est appelée par l'application, cette fonction là n'est pas appelée du coup il n'efface pas les évènements et ça me fait comme si l'évènement est généré à chaque tour de boucle : 

    void Command::clearEventsStack ()
            {
                if (sname == "EXTERNAL")
                    std::cout<<"clear event stack"<<std::endl;
                events.clear();
            }

    C'est comme si j'avais deux applications différentes, pourtant il ajoute bien les évènements ici :

    void Command::pushEvent (window::IEvent& event)
            {
                if (sname == "EXTERNAL")
                    std::cout<<"push event"<<std::endl;
                std::vector<window::IEvent>::iterator it;
                bool containsEvent = false;
                for (it = events.begin(); it != events.end(); it++)
                {
                    if (equalEvent(event, *it))
                        containsEvent = true;
                }
                if (!containsEvent) {
                    events.push_back(event);
                }
            }

    Bref, je ne comprend absolument pas ou est le problème si il appelle bien la fonction pushEvent il devrait aussi appeler la fonction clearEventsStack

    EDIT : j'ai fait un test ici : 

    void render() {
                    if (windows.size() != 0 && windows[0].first->isOpen()) {
                        for (unsigned int i = 0; i < windows.size(); i++) {
                            //windows[i].first->setActive(true);
                            windows[i].first->clear(clearColor);
                        }
                        onRender(componentManager.get());
                        componentManager->clearComponents();
                        if (eventContextActivated) {
                           listener->processEvents();
                        }
                        componentManager->updateComponents();
                        if (name == "EXTERNAL")
                            std::cout<<"appli clear event stack"<<std::endl;
                        Command::clearEventsStack();
                        componentManager->drawRenderComponents();
                        onDisplay(windows[0].first);
                        componentManager->drawGuiComponents();
                        for (unsigned int i = 0; i < windows.size(); i++)
                            windows[i].first->display();
                    }
                }

    Il affiche bien "appli clear event stack" mais il n'appelle pas clearEventsStack de la classe Command : 

    void Command::clearEventsStack ()
            {
                if (sname == "EXTERNAL")
                    std::cout<<"clear event stack"<<std::endl;
                events.clear();
            }


    il n'affiche pas clear event stack.

    Je trouve pas ça très normal.

    bug mingw je pense.

    -
    Edité par OmbreNoire 9 janvier 2021 à 2:02:18

    • Partager sur Facebook
    • Partager sur Twitter
      9 janvier 2021 à 9:55:15

      OmbreNoire a écrit:

      bug mingw je pense.

      Peu probable.

      J'ai rien compris. Tes explications sont un peu bordelique et ton code est un peu borelique. Je ne serais pas surpris que ta pensee le soit aussi.

      Essaie de faire un exemple minimal (dans un nouveau projet) qui reproduit le probleme, en detaillant comment nous on peut reproduire.

      • Partager sur Facebook
      • Partager sur Twitter
        9 janvier 2021 à 10:51:15

        Bonjour,

        Il a y peu de chance de créer un fonction libre ou statique en double. Il est plus probable de dupliquer des données. Bien vérifier que tes deux variables sname et events sont des statiques définies une seule fois dans un unique fichier cpp compilé et linké une seule fois.

        • Partager sur Facebook
        • Partager sur Twitter

        En recherche d'emploi.

          9 janvier 2021 à 15:59:50

          Je pense que le problème est qu'il crée les variables statiques en double car je link la librairie à la compilation de mon application et lors de la génération du .so (obligé sinon j'ai des "undefined references errors")

          Bref, je vois pas comment réglé ce problème je pense pas qu'il y ai vraiment une solution...

          • Partager sur Facebook
          • Partager sur Twitter
            9 janvier 2021 à 17:21:34

            Cela me rappelle vaguement quelque chose dans mon ancienne entreprise. Un collègue faisait aussi des variables statiques dans des plugins et on avait des résultats étrange de mémoire (cela remonte à 2013, j'essaye de raviver ma mémoire). Si je me souviens bien, le résultat est qu'on avait deux variables différentes : une dans le plugin et une dans l'application hôte.

            De toute façon, mélanger statique, dynamique et des bibliothèques chargées dynamiquement c'est assez casse gueule.

            La recommandation que je pourrais faire c'est que tes bibliothèques doivent rester pures au maximum.

            -
            Edité par markand 9 janvier 2021 à 17:22:02

            • Partager sur Facebook
            • Partager sur Twitter

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

              9 janvier 2021 à 17:49:44

              C'est le problème avec le c++ les variables statiques doivent être créer dans un .cpp et sont crées au linkage et donc lorsque l'on doit utiliser deux fois une librairie lors d'une même exécution les variables statiques sont créer en double. Ce que je veux faire c'est que comme je ne connais pas la définition de la classe que l'utilisateur va crée à l'avance,  l'utilisateur crée un plugin qui herite d'une classe de base et l'application récupère des informations sur le plugin (constructeur, fonctions, etc...) et je crée l'objet et le modifie avec l'application sachant que l'application affiche les informations de la classe de base. Et comme j'affiche ses informations avec une gui et que le vecteur qui stocke les événements est statistique et que je lie deux fois la librairie qui gère les gui et les événements, les variables statiques sont créer en double et il n'y a pas d'options pour que le compilateur ne crée pas les variables statiques en double bref je vais devoir revoir mon idée.

              EDIT : bon j'ai trouvé une solution dégueulasse mais je n'ai pas d'autre choix, j'ai retiré la variable statique, je l'ai remplacée par une variable membre et je push les évènements pour chaque action. Etant donné que je les push pour chaque action et plus une seule fois, j'ai une chute du FPS.

              -
              Edité par OmbreNoire 9 janvier 2021 à 18:48:30

              • Partager sur Facebook
              • Partager sur Twitter
                9 janvier 2021 à 23:30:49

                Marrant, mais ta solution dégueulasse me parait plus propre que d'avoir une variable statique (enfin bon, tout me paraît plus propre qu'une variable statique)

                Je comprends pas pourquoi ton tableau d'évènements devrait être statique, en fait...

                • Partager sur Facebook
                • Partager sur Twitter

                Si vous ne trouvez plus rien, cherchez autre chose.

                  10 janvier 2021 à 14:27:12

                  Peut être parce que la pile d'évènement est la même pour toutes les commandes, pour ça que j'avais fait une variable statique.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 janvier 2021 à 18:18:37

                    Ahlala, @OmbreNoire, le champion olympique de la découverte de bugs dans des machins utilises par des centaines de milliers de développeurs sur plusieurs années, passons.

                    Alors, comme @dragonjoker, les statics, c'est dans 98% des cas, une grosse variable globale bien dégueulasse, donc, prouves-nous qu'on n'est bien dans les 2% "legit".

                    Je ne connais pas le linker que tu utilises, mais si on sait causer à mon linker préféré (LINK sous Windows, dans Visual Studio en générale), il est tout à fait ouvert au partage de ces statiques bien dégueu entre modules binaires :

                    https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/h90dkhs0(v=vs.90)?redirectedfrom=MSDN

                    Les développeurs de votre chaîne de compilation ne sont pas plus cons que les autres, faudrait juste que les utilisateurs prennent la peine de lire la documentation.

                    Sans "ABI" commune, ni modules (c'est pour quand???), faire un mécanisme de greffon en C++ orienté objet, c'est vraiment juste pour faire du bricolage à pas cher.

                    Pourquoi ne pas passer par une ABI fixée, comme celle du C ? Quitte à faire l'enrobage objets dans des headers ? Ou vous voulez juste chercher à avoir la max d'emmerde, peut-être ?

                    -
                    Edité par bacelar 10 janvier 2021 à 18:18:54

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

                      Après réflexion je ne pense pas qu'utiliser une variable statique bien dégueulasse est vraiment nécessaire même si l'application est plus rapide avec, le fait de la partager risquerait de la ralentir car il faut sûrement utiliser des mutex ou se genre de choses bien dégueulasse comme lorsque l'on fait du multithread.

                      De plus je ne sais absolument pas comment on fait avec le linker de mingw pour partager une variable statique entre un .so et une application, je n'ai pas trouvé de documentation là dessus!

                      Donc, pour éviter à avoir à faire ce genre de choses j'ai utilisé une variable membre plutôt qu'une variable statique.

                      Pour partager une variable, entre mon .so et l'application, le .so appelle une fonction de l'application et je passe un pointeur vers l'entité créée dans le .so et pour passer une variable de l'application au .so je passe un pointeur dans la fonction du .so lorsque j'appelle la fonction du .so.

                      Par contre, je ne sais pas quelle est la portée d'une variable globale créée dans un .so :

                      #define ENTITYquesty
                      #include "C:/Users/Laurent/Projets/ODFAEGCREATOR/Test/Scripts/pnj.hpp"
                      #include <fstream>
                      #include <iostream>
                      #include <vector>
                      #include <string>
                      #include "odfaeg/Core/archive.h"
                      #include "odfaeg/Core/class.hpp"
                      #include "../../Windows/Demos/ODFAEGCREATOR/application.hpp"
                      extern "C" {
                          void createObject(ODFAEGCreator* c);
                          void readObjects (ODFAEGCreator* c);
                      }
                      std::vector<odfaeg::graphic::Entity*> vPnj;
                      void createObject(ODFAEGCreator *c) {
                         EXPORT_CLASS_GUID(EntityPnj,odfaeg::graphic::Entity,sorrok::Pnj)
                          if(vPnj.size() == 0) {
                             odfaeg::graphic::Entity *questy = new sorrok::Pnj ();
                             vPnj.push_back(questy);
                             #ifdef ENTITYquesty
                                 c->addExternalEntity(questy);
                             #endif
                         }
                         std::ofstream ofPnj ("Pnj.oc");
                         odfaeg::core::OTextArchive oaPnj (ofPnj);
                         oaPnj(vPnj);
                      }
                      void readObjects (ODFAEGCreator *c) {
                         EXPORT_CLASS_GUID(EntityPnj,odfaeg::graphic::Entity,sorrok::Pnj)
                         std::ifstream ifPnj ("Pnj.oc");
                         odfaeg::core::ITextArchive iaPnj (ifPnj);
                         iaPnj(vPnj);
                         #ifdef ENTITYquesty
                             for (unsigned int i = 0; i < vPnj.size(); i++)
                                 c->addExternalEntity(vPnj[i]);
                             c->updateNb("Pnj",vPnj.size());
                         #endif
                      }

                      Lorsque je vais créer une deuxième entité pnj par exemple ici :

                      if (button == bCreateObject) {
                              std::vector<std::string> parts = split(dpSelectClass->getSelectedItem(), "::");
                              Class cl = Class::getClass(parts[parts.size()-1]);
                              std::string headerFile = cl.getFilePath();
                              convertSlash(headerFile);
                              int nb = 0;
                              std::map<std::string, unsigned int>::iterator it = nbs.find(cl.getName());
                              if (it != nbs.end()) {
                                  nb - it->second;
                              } else {
                                  updateNb(cl.getName(), nb);
                              }
                              //std::cout<<"header file : "<<headerFile<<std::endl;
                              std::ifstream ifs("sourceCode.cpp");
                              std::string sourceCode="";
                              bool fileExist = false;
                              if (ifs) {
                                  fileExist = true;
                                  std::string line;
                                  while (getline(ifs, line)) {
                                      sourceCode += line+"\n";
                                  }
                                  ifs.close();
                              } else {
                                  sourceCode += "#include <fstream>\n";
                                  sourceCode += "#include <iostream>\n";
                                  sourceCode += "#include <vector>\n";
                                  sourceCode += "#include <string>\n";
                                  sourceCode += "#include \"odfaeg/Core/archive.h\"\n";
                                  sourceCode += "#include \"odfaeg/Core/class.hpp\"\n";
                                  sourceCode += "#include \"../../Windows/Demos/ODFAEGCREATOR/application.hpp\"\n";
                                  sourceCode += "extern \"C\" {\n";
                                  sourceCode += "    void createObject(ODFAEGCreator* c);\n";
                                  sourceCode += "    void readObjects (ODFAEGCreator* c);\n";
                                  sourceCode += "}\n";
                                  sourceCode += "void createObject(ODFAEGCreator *c) {\n";
                                  sourceCode += "}\n";
                                  sourceCode += "void readObjects (ODFAEGCreator *c) {\n";
                                  sourceCode += "}\n";
                              }
                              std::string sourceFile = cl.getSourcePath();
                              //std::cout<<"source file : "<<sourceFile<<std::endl;
                              if (sourceCode.find("#include \""+headerFile+"\"") == std::string::npos) {
                                  sourceCode.insert(0, "#include \""+headerFile+"\"\n");
                                  std::vector<odfaeg::core::Class> superClasses = cl.getSuperClasses();
                                  bool found = false;
                                  while (superClasses.size() > 0 && !found) {
                                      for (unsigned int i = 0; i < superClasses.size() && !found; i++) {
                                          std::cout<<"super class name : "<<superClasses[i].getName()<<std::endl;
                                          if (superClasses[i].getName() == "Entity") {
                                              std::cout<<"found entity!"<<std::endl;
                                              found = true;
                                          }
                                          std::vector<odfaeg::core::Class> tmpSuperClasses = superClasses[i].getSuperClasses();
                                          for (unsigned int j = 0; j < tmpSuperClasses.size(); j++) {
                                              superClasses.push_back(tmpSuperClasses[j]);
                                           }
                                           if (superClasses.size() > 0)  {
                                              superClasses.erase(superClasses.begin(), superClasses.begin()+1);
                                           }
                                      }
                                  }
                                  if (found) {
                                      sourceCode.insert(0, "#define ENTITY"+taObjectName->getText()+"\n");
                                  }
                                  std::string toInsert = "";
                                  int pos;
                                  if (sourceCode.find("}") != std::string::npos) {
                                      pos = sourceCode.find("}")+2;
                                      if (dpSelectPointerType->getSelectedItem() == "No pointer") {
                                          if (cl.getNamespace() != "") {
                                              toInsert = "std::vector<"+cl.getNamespace()+"::"+cl.getName()+"> v"+cl.getName()+";\n";
                                          } else {
                                              toInsert = "std::vector<"+cl.getName()+"> v"+cl.getName()+";\n";
                                          }
                                      } else {
                                          toInsert = "std::vector<"+dpSelectPointerType->getSelectedItem()+"*> v"+cl.getName()+";\n";
                                      }
                                      sourceCode.insert(pos, toInsert);
                                      toInsert = "";
                                      std::string toFind = "void createObject(ODFAEGCreator *c) {";
                                      pos = sourceCode.find(toFind)+toFind.size()+1;
                                      if (dpSelectPointerType->getSelectedItem() != "No pointer" && dpSelectPointerType->getSelectedItem() != dpSelectClass->getSelectedItem()) {
                                          std::vector<std::string> parts = split(dpSelectPointerType->getSelectedItem(), "::");
                                          std::string name = parts[parts.size()-1];
                                          toInsert += "   EXPORT_CLASS_GUID("+name+cl.getName()+","+dpSelectPointerType->getSelectedItem()+","+dpSelectClass->getSelectedItem()+")\n";
                                      }
                                      toInsert += "   std::ofstream of"+cl.getName()+" (\""+cl.getName()+".oc\");\n";
                                      toInsert += "   odfaeg::core::OTextArchive oa"+cl.getName()+" (of"+cl.getName()+");\n";
                                      toInsert += "   oa"+cl.getName()+"(v"+cl.getName()+");\n";
                                      sourceCode.insert(pos, toInsert);
                                      toInsert = "";
                                      toFind = "void readObjects (ODFAEGCreator *c) {";
                                      pos = sourceCode.find(toFind)+toFind.size()+1;
                                      if (dpSelectPointerType->getSelectedItem() != "No pointer" && dpSelectPointerType->getSelectedItem() != dpSelectClass->getSelectedItem()) {
                                          std::vector<std::string> parts = split(dpSelectPointerType->getSelectedItem(), "::");
                                          std::string name = parts[parts.size()-1];
                                          toInsert += "   EXPORT_CLASS_GUID("+name+cl.getName()+","+dpSelectPointerType->getSelectedItem()+","+dpSelectClass->getSelectedItem()+")\n";
                                      }
                                      toInsert += "   std::ifstream if"+cl.getName()+" (\""+cl.getName()+".oc\");\n";
                                      toInsert += "   odfaeg::core::ITextArchive ia"+cl.getName()+" (if"+cl.getName()+");\n";
                                      toInsert += "   ia"+cl.getName()+"(v"+cl.getName()+");\n";
                                      toInsert += "   #ifdef ENTITY"+taObjectName->getText()+"\n";
                                      toInsert += "       for (unsigned int i = 0; i < v"+cl.getName()+".size(); i++)\n";
                                      toInsert += "           c->addExternalEntity(v"+cl.getName()+"[i]);\n";
                                      toInsert += "       c->updateNb(\""+cl.getName()+"\",v"+cl.getName()+".size());\n";
                                      toInsert += "   #endif\n";
                                      sourceCode.insert(pos, toInsert);
                                  }
                              }
                      
                              std::vector<std::string> argValues;
                              for (unsigned int i = 0; i < tmpTextAreas.size(); i++) {
                                  argValues.push_back(tmpTextAreas[i]->getText());
                              }
                              if(sourceCode.find("std::ofstream of"+cl.getName()+" (\""+cl.getName()+".oc\");\n") != std::string::npos) {
                                  int pos = sourceCode.find("std::ofstream of"+cl.getName()+" (\""+cl.getName()+".oc\");\n")-3;
                      
                      
                                  std::string args;
                                  for (unsigned int j = 0; j < argValues.size(); j++) {
                                      args += argValues[j];
                                      if (j != argValues.size()-1) {
                                          args += ",";
                                      }
                                  }
                                  std::string toInsert = "    if(v"+cl.getName()+".size() == "+conversionIntString(nb)+") {\n";
                                  if (dpSelectPointerType->getSelectedItem() == "No pointer") {
                                      if (cl.getNamespace() != "") {
                                          toInsert += "       "+cl.getNamespace()+"::"+cl.getName()+" "+taObjectName->getText()+" = "+cl.getNamespace()+"::"+cl.getName()+" ("+args+");\n";
                                      } else {
                                          toInsert += "       "+cl.getName()+" "+taObjectName->getText()+" ("+args+");\n";
                                      }
                                  } else {
                                      toInsert += "       "+dpSelectPointerType->getSelectedItem()+" *"+taObjectName->getText()+" = new "+dpSelectClass->getSelectedItem()+" ("+args+");\n";
                                  }
                                  toInsert += "       v"+cl.getName()+".push_back("+taObjectName->getText()+");\n";
                                  toInsert += "       #ifdef ENTITY"+taObjectName->getText()+"\n";
                                  toInsert += "           c->addExternalEntity("+taObjectName->getText()+");\n";
                                  toInsert += "       #endif\n";
                                  toInsert += "   }\n";
                                  sourceCode.insert(pos, toInsert);
                              }
                              //std::cout<<"source code : "<<sourceCode<<std::endl;
                              std::ofstream file("sourceCode.cpp");
                              file<<sourceCode;
                              file.close();
                      
                              rtc.addSourceFile("sourceCode");
                              rtc.compile();
                              std::string errors = rtc.getCompileErrors();
                              //std::cout<<"errors : "<<rtc.getCompileErrors();
                              rtc.run<void>("createObject", this);
                              wCreateNewObject->setVisible(false);
                              getRenderComponentManager().setEventContextActivated(false, *wCreateNewObject);
                              tScriptEdit->setEventContextActivated(true);
                          }

                      et que je vais recompilé et relinké le .so, est ce que le vecteur "vPnj" va être réinitialisé et le premier l'objet "questy" réalloué ou bien non ?

                      Si oui, ça va poser problème car, lorsque je vais modifier l'objet "questy" dans l'éditeur de map, si il réalloue le pointeur, toutes les modifications seront perdues.

                      Du coup il va falloir que je trouve une autre solution en créant le vecteur dans l'application plutôt que dans le .so pour que le vecteur ne soit pas vidé tant que l'on ne ferme pas l'application. Mais dans ce cas comment séparer les vecteurs d'entités de type pnj, monster, etc... pour les sauvegarder dans des fichiers séparer ? Sachant que je veux que :

                      -L'utilisateur n'aie pas besoin de modifier le code source de l'éditeur lorsqu'il crée un nouveau script et qu'il veut créer un objet de ce nouveau script.

                      -Les classes faisant parties du gameplay sont fort différentes selon le type de jeux, l'utilisateur devra donc créer les scripts de ses classes lui même.

                      -Les objets de différents types soient sauvegardé dans des fichiers à part que l'utilisateur pourra chargé dans le jeux, grâce à la sérialisation.





                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 janvier 2021 à 2:10:18

                        >une variable statique bien dégueulasse est vraiment nécessaire même si l'application est plus rapide avec

                        D'où vous sortez qu'une variable statique est "plus rapide" que la solution X ou Y ???

                        A part niquer les caches, je vois pas trop d'avantages à ces variables statiques (ironie inside).

                        >car il faut sûrement utiliser des mutex ... bien dégueulasse comme lorsque l'on fait du multithread.

                        Bin non, si tu fais pas de multi-thread, il n'y a pas besoin de mutex et autres cochonneries. Mais qui programme en mono-thread de nos jours ?

                        >De plus je ne sais absolument pas comment on fait avec le linker de mingw

                        J'y connais quasiment plus rien en truc de pingouin, mais une simple recherche avec notre ami à tous : "mingw /SECTION: RWS" me donne ça en 1er hit :

                        https://mingw-users.narkive.com/eoUc0jmU/shared-sections

                        Je pense pas que c'est de la "rocket science" que de chercher sur Google, non ? (en plus, ça semble bien plus carré que sous MSVC)

                        En plus, c'est super-chelou, vous parlez de ".so" spécifique aux systèmes *NIX, mais vous avez des chemins Windows (complètement absurdes) dans vos includes. C'est quoi votre mélange ???

                        Vous cherchez les emmerdes.

                        Et arrêtez de faire nimportnawak avec ces chemins d'include à rallonge et en dur. Configurez correctement votre IDE/chaîne de compilation pour que ces chemins vers les fichiers d'en-tête aient des longueurs et une structure RAISONNABLE.

                        >Donc, pour éviter à avoir à faire ce genre de choses j'ai utilisé une variable membre plutôt qu'une variable statique.

                        C'est votre Design qui doit piloter vos choix, pas votre ignorance.

                        >le .so appelle une fonction de l'application et je passe un pointeur vers l'entité créée dans le .so

                        Une librairie ne devrait rien connaitre de l'exécutable qui la charge, sauf les API abstraites, c'est dans l'autre sens que doivent se faire les dépendances, s'il y en a (Dependency Inversion).

                        >et pour passer une variable de l'application au .so je passe un pointeur dans la fonction du .so lorsque j'appelle la fonction du .so

                        Là, c'est bien plus raisonnable. Après, rien ne vous empêche de faire en sorte qu'un des paramètre de cette fonction 'app->so' contient un pointeur vers les implémentations des API abstraite dans l'application.

                        Si possible, essayez de "carrosser" le plus possible ces pointeurs nus pour ne pas vous tirez une balle dans le pied.

                        >Par contre, je ne sais pas quelle est la portée d'une variable globale créée dans un .so :

                        Comme indiquer dans ma précédente réponse, c'est fonction des paramètres donnés à votre éditeur de lien.

                        NON, MAIS, C'EST QUOI CES CHEMINS VERS LES FICHIERS D'EN-TETE TOUT POURRI !?!?!

                        Corrigez ces chemins d'includes fissa !!!

                        >EXPORT_CLASS_GUID

                        Heu, vous êtes sûr que c'est à mettre dans une simple fonction et pas dans l'espace globale ou dans une autre MACRO "dédiée" ???

                        Ligne 18, caca ce "new". Il est où le delete correspondant ? En vacances aux Seychelles ?

                        Non, mais c'est quoi cette horreur de code source dans des chaines ???

                        Utilisez des trucs comme du T4 ou autres formats pour générer du code source et pas ces infâmes concaténations.

                        Et des "#ifdef" dans du code généré à la volée, c'est ubuesque, pensez au KISS (Keep It Simple and Stupid).

                        J'ai du mal à voir comment une personne qui a un code si bordélique puisse créer des MACRO d'EXPORT aussi "carrée" ou un système de réflexion de type aussi "clean". Code Frankenstein ?

                        >et que je vais recompilé et relinké le .so

                        Ok, d'accord, mais vous recharger comment votre nouveau bidule dans la mémoire adressée par l'exécutable ? Par l'action du Saint-Esprit ?

                        >est ce que le vecteur "vPnj" va être réinitialisé et le premier l'objet "questy" réalloué ou bien non ?

                        Bin, c'est plutôt comment vous déchargez et rechargez ces ".so" qui pourrait vous l'indiquer.

                        Généralement, dans un éditeur de map, on édite pas du code, on change des paramètres et, à la rigueur on change des SCRIPTS, pas des modules binaires.

                        Si vous voulez vraiment faire un éditeur de map instable, vous n'avez qu'à prévoir une fonction dans le greffon qui s'occupera de faire le ménage (sauvegarde des données qu'il gère comprise), faire en sorte que le programme/application décharge le ".so", et le recharge après compilation et que le greffon recharge ce que son ancienne version avait sauvegardé.

                        >comment séparer les vecteurs d'entités de type pnj, monster, etc... pour les sauvegarder dans des fichiers séparer ?

                        Pourquoi chaque module binaire (application et ".so") ne gère pas ses informations de manière autonomes ???

                        >lorsqu'il crée un nouveau script

                        Bin, s'il avait un langage de script (LUA, Python, etc...) et pas un langage compilé comme le C++, ça serait déjà largement moins usine à gaz, votre machin.

                        >et qu'il veut créer un objet de ce nouveau script.

                        Comment vous passez de "objet" à script ? L'un est concept de la POO (avec une API, etc...), l'autre est un machin complètement arbitraire, peut-être avec du code, peut-être structuré en fonction, peut-être avec des constantes et des variables globales dans tous les coins.

                        Le code binaire ne se sérialise pas.

                        Il faut que vous soyez plus clair sur votre architecture générale : type de conception générale (ECS, pipeline, ...) , APIs/Services définis et implémentés par l'application à l'usage des greffons, les API que définis l'application mais que les greffons doivent implémenter.

                        Vous avez déjà des trucs à base de GUID, qu'est-ce qui vous empêche de vous en servir pour communiquer dynamiquement les APIs supportés ???

                        Maîtrisez-vous un minimum les outils que vous semblez utiliser : Une architecture à base de composant (EXPORT_CLASS_GUID) et le système de réflexion (getClass, etc...).

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                        Fonction statique pas appelée.

                        × 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