List<boost any> Strings verschwinden bei Übergabe



  • folgendes Problem...

    Habe eine Liste
    folgenden Typs:

    using boost::any_cast;
    typedef std::list<boost::any> many;
    

    aus einem Hauptprogramm rufe ich eine Funktion in einer .so File auf

    boost::shared_ptr<ModulInput> modul( *((boost::shared_ptr<ModulInput>*)input) );
           values_from_input = modul->inputer(*LoadModul, values);
    

    in der .so File ist der Typ definiert.. (siehe oben)
    und dann noch u.a. folgender Funktionscode:

    class ModulI : public ModulInput
    {
    public:
            ModulI() {
    		std::cout << "new" << std::endl;
    	}
    
    	virtual ~ModulI() {
    		std::cout << "delete" << std::endl;
    	}
    
    	virtual many inputer(TModulK & LoadModul, many & values)
    	  {
    
               std::string Filename;
    	   std::string Parameter;
    
    	   cout<< endl<<"Hier steht der in TModulK* LoadModul übermittelte Modulname und der erste Parameter"<<endl;
    
    	   Filename = LoadModul.mod_name;
               cout<< "Mod_Name: " << Filename<<endl;
               // Zugriff auf die Parameter ist etwas komisch, aber geht
    	   // erst Punkt dann Pfeil
               Parameter = LoadModul.ParaHook->par_value;
               cout << "Parameter 1: "<< Parameter<<endl<<endl;
    
    	   // für diese Funktion muss die Header Datein outputfunc.h eingebunden werden
               // und beim compilieren die outputfunc.cpp angegeben werden
    	   OutputParameter(LoadModul.ParaHook);
    
               cout <<endl<< "IN INPUT MODUL ANGEKOMMEN!!!" << endl;
    
    	    for (int a = 1; a<=10; a++)
                {
                 append_any(values,12345);
                 append_any(values,11111);
                 append_any(values,"löschen");
                 append_int(values,22222);
                 append_any(values,"als Char_ptr");
                 append_nothing(values);  // nichts anfügen...
                 append_string(values,"ich bin String-Wert");
                 append_int(values,54321);
    
                }
    
    	    // Werte via Variable hinzufügen
                int wert;
    	    wert = 9999999;
    	    append_any(values,wert);
    
    	   count_all(values);
               print_all(values);
    
    	   return values;
    
    	  }
    };
    extern "C" {boost::shared_ptr<ModulInput> inputer( new ModulI() ); }
    

    als Ausgabe bei count_all(values) gibt er folgendes auf Konsole aus

    IN INPUT MODUL ANGEKOMMEN!!!
    #int == 41
    #empty == 10
    #string == 10
    #const char * == 20

    wie ihr seht gebe ich am Schluss

    return values;
    

    zurück in das Hauptprogramm...

    in diesem wird das ganze in

    values_from_input
    

    gespeichert...

    sobald ich nun die Work Funktion im Work Modul (neue .so File) aufrufe

    values_from_work = wmodul->worker(*LoadModul, values_from_input);
    

    und in der Funktion worker in der .so Datei (im Prinzip der selbe aufbau nur andere bezeichner was Funktionsname betrifft... dann wieder

    count_all(values);
    

    mache

    gibt er auf Konsole folgendes aus:

    In WORK MODUL ANGEKOMMEN!!!
    #int == 41
    #empty == 10
    #string == 0 // Wieso sind hier keine String Werte mehr
    #const char * == 20

    die Frage ist nur...

    wo zum Geier sind die String Werte hin??

    kann es sein das es sich hier um das Problem handelt das man String Werte nicht einfach "kopieren" kann 🙄

    weiss jemand nee Lösung wie ich die String Werte auch in der Work Funktion verfügbar habe

    Wird das von list<boost any> nicht unterstützt??? 😮

    bräuchte dringends eine Lösung!!! 😋

    Merci UFO



  • Warum zeigst du uns nicht einfach die Funktion die beim Verschwinden der Strings aufgerufen wird?

    Und warum hast du so umständliche append-Funktionen?


  • Mod

    Zeig doch mal die count_all Funktion. Ich vermute, dass hier ein Problem beim type_info-Vergleich vorliegt.



  • Hier die Funktion im Main Programm in der die Libs geladen werden und die Funktionen aufgerufen werden

    void LoadLibs(int queue_id)
    {
      const char *filename;
      const char *funcname;
      //const char *dlsym_error;
    
      TModulK *LoadModul = NULL;
      TQueueK *LoadQueue = NULL;
    
      LoadQueue = SearchQueue(queue_id);
    
      // Input
    
      LoadModul = SearchModul(LoadQueue->queue_input);
      filename = LoadModul->mod_name.c_str();
    
      void* inputHand = dlopen(filename, RTLD_LAZY);  
    
      if (!inputHand)
         {
          cerr << "Cannot load library: " << dlerror() << endl;
          return 1;
         }
        {
    
           funcname = LoadModul->func_name.c_str();
    
           cout <<"name der Datei:"<< filename <<endl;
           cout << "Name der Funktion: "<< funcname<< endl;
    
           void * input = dlsym(inputHand,funcname);
    
           if(!input) {
             std::cerr << "error dlsym(): " << dlerror() << std::endl;
             dlclose(input);
              return 1;     //wenn dieses Return 1 fehlt dann Speicherschutzverletzung
             }
    
           boost::shared_ptr<ModulInput> modul( *((boost::shared_ptr<ModulInput>*)input) );
           values_from_input = modul->inputer(*LoadModul, values);
    
           // return 1;  //sobald hier return 0 oder 1 geht er nicht mehr weiter
         }
    
         // Hier dlclose(inputHand); beendet funktion und er gibt das Hier1 gar nicht mehr aus...
         // wenn ich dlclose(inputHand); weglasse dann geht er weiter
    
         cout << "Hier1"<<endl;
    
      // WORK   
    
      LoadModul = SearchModul(LoadQueue->queue_work);
           cout << "Hier1a"<<endl;
      filename = LoadModul->mod_name.c_str();
    
                cout << "Hier2"<<endl;
    
      void* workHand = dlopen(filename, RTLD_LAZY);
    
      if (!workHand)
         {
          cerr << "Cannot load library: " << dlerror() << endl;
          return 1;
         }
         {
    
              cout << "Hier3"<<endl;
           funcname = LoadModul->func_name.c_str();
    
           cout <<"name der Datei:"<< filename <<endl;
           cout << "Name der Funktion: "<< funcname<< endl;
    
           void * work = dlsym(workHand,funcname);
    
           if(!work) {
             std::cerr << "error dlsym(): " << dlerror() << std::endl;
             dlclose(workHand);
              return 1;     //wenn dieses Return 1 fehlt dann Speicherschutzverletzung
             }
    
           boost::shared_ptr<ModulWork> wmodul( *((boost::shared_ptr<ModulWork>*)work) );
           values_from_work = wmodul->worker(*LoadModul, values_from_input);
    
          // return 0;  
         }
    
             if (!workHand)
          { // Do nothing
          }
       else
          {
           dlclose(workHand);
           cout << "Work-Handle closed"<< endl;
          }
    
           if (!inputHand)
          { // Do nothing
          }
       else
          {
           dlclose(inputHand);
           cout << "Input-Handle closed"<< endl;
          }
    
       return  EXIT_SUCCESS;
    }
    

    dann noch die

    count_all Funktion

    void count_all(many & values)
    {
        std::cout << "#int          == "
            << std::count_if(values.begin(), values.end(), is_int) << std::endl;
        std::cout << "#empty        == "
            << std::count_if(values.begin(), values.end(), is_empty) << std::endl;
        std::cout << "#string       == "
            << std::count_if(values.begin(), values.end(), is_string) << std::endl;
    
        std::cout << "#const char * == "
            << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;
    
        std::cout<<std::endl;
    }
    

    wobei diese direkt von hier stammt

    http://www.boost.org/doc/html/any/s02.html

    ach ja... wenn ich die print_all funktion beim zweiten mal (also in work aufrufe) dann zeugt er keine strings an....



  • Boost.Any und Shared Libraries funktionieren nur zusammen wenn du auf ein paar GCC-Flags achtest. Probier mal -rdynamic (beim Linken).



  • Mr. N schrieb:

    Boost.Any und Shared Libraries funktionieren nur zusammen wenn du auf ein paar GCC-Flags achtest. Probier mal -rdynamic (beim Linken).

    mache ich bereits seit begin des Projektes...

    sowohl bei dem compilieren der Shared Objekts als auch unter Kdevelop beim Main Programm verwende ich -rdynamic -shared

    im KDevelop noch zusätzlich -ldl



  • UFOSWORLD schrieb:

    Mr. N schrieb:

    Boost.Any und Shared Libraries funktionieren nur zusammen wenn du auf ein paar GCC-Flags achtest. Probier mal -rdynamic (beim Linken).

    mache ich bereits seit begin des Projektes...

    sowohl bei dem compilieren der Shared Objekts als auch unter Kdevelop beim Main Programm verwende ich -rdynamic -shared

    im KDevelop noch zusätzlich -ldl

    Außerdem solltest du dlopen denke ich mit RTLD_GLOBAL aufrufen.

    (Und dann gabs noch nen Trick an den ich mich nicht erinnere.)



  • Mr. N schrieb:

    UFOSWORLD schrieb:

    Mr. N schrieb:

    Boost.Any und Shared Libraries funktionieren nur zusammen wenn du auf ein paar GCC-Flags achtest. Probier mal -rdynamic (beim Linken).

    mache ich bereits seit begin des Projektes...

    sowohl bei dem compilieren der Shared Objekts als auch unter Kdevelop beim Main Programm verwende ich -rdynamic -shared

    im KDevelop noch zusätzlich -ldl

    Außerdem solltest du dlopen denke ich mit RTLD_GLOBAL aufrufen.

    (Und dann gabs noch nen Trick an den ich mich nicht erinnere.)

    mhhh also das mit dem RTLD_GLOBAL funzt nicht...

    nachdem ich das geändert habe motzt er beim ausführen nun rum, das er die .so File nicht mehr findet die in filename drin steht... obwohl der LD_LIBRARY_PATH gestetzt ist
    auch das kopieren ins Programmverzeichniss der .so files bringt keine Besserung



  • UFOSWORLD schrieb:

    mhhh also das mit dem RTLD_GLOBAL funzt nicht...

    nachdem ich das geändert habe motzt er beim ausführen nun rum, das er die .so File nicht mehr findet die in filename drin steht... obwohl der LD_LIBRARY_PATH gestetzt ist
    auch das kopieren ins Programmverzeichniss der .so files bringt keine Besserung

    Probier mal ob boost::unsafe_any_cast geht (das ist allerdings __böse__). Dazu brauchst du allerdings mindestens ein gepatchtes Boost 1.33.1. Die Version von Ubuntu Edgy Eft zB geht IIRC.



  • also unsafe_an_cast kompiliert (Ver 1.34.0 am laufen) er durch, nur beim ausführen mit RTLD_GLOBAL bei dlopen kommt der selbe Fehler wie vorher... kann die .so File nicht finden...

    ändere ich das wieder um auf RTLD_LAZY dann läuft er durch aber wieder mit dem selben Fehler, also Speicherschutzgfehler und fehlenden String Werten im Work Modul....

    vielleicht handelt es sich ja doch um das alte Problem mit kopieren von Stringwerten... dachte zwar das in C++ jetzt das zuweisen von Strings funkioniert und erlaubt ist... aber man wird ja immer mal wieder Überrascht...

    (siehe Vermutung am Ende erster Post in diesem Beitrag)

    noch irgendwelche TIPS??? 😞 😞 😞



  • UFOSWORLD schrieb:

    noch irgendwelche TIPS??? 😞 😞 😞

    Mach mal ein lesbareres und kleineres Codebeispiel, das das gleiche Problem aufweist. Deinen Code da oben habe ich mir nämlich nicht wirklich durchgelesen.


Anmelden zum Antworten