Problem mit Shared Libraries



  • Hallo,

    ich habe ein Problem mit meinen Shared Libraries.
    Und zwar moechte bzw. muss ich, um das ganze dynamisch und modular zu halten,
    die libs bzw. eigentlich den Rueckgabewert (sozusagen eine "Methodentabelle")
    als verkettete Liste speichern. Dies geschieht zu Beginn der Main in der Methode
    init_libs.
    In den libs selbst wird eine Methode aufgerufen, die mir sozusagen
    die Pointer auf die eigentliche Methode, die ich aufrufen will, "umbiegt" und
    diese "Methodentabelle" zurueckgibt.
    Da die Pointer nun auf die entsprechenden Methoden gesetzt sind, kann ich
    nun einfach die Methode process() aufrufen und es wird dann die eigentlich
    gewuenschte Methode der lib ausgefuehrt.

    Mein eigentliches Problem bekomme ich allerdings erst in der main(). Und zwar
    wenn ich auf die entsprechenden Methodentabellen wieder zugreifen will:
    datastruct = filter_table.process(datastruct);
    filter_table ist hier diese Methodentabelle, wo die Pointer nun auf process() zeigen.
    Hier bekomme ich dann beim Ausfuehren des Programms eine "Illegal Instruction"
    und des Programm bricht ab.

    Ich habe keine Ahnung was ich da falsch mache. Die entsprechenden Stellen im
    Quellcode habe ich unten mal rangehangen. Ich hoffe ich habe das oben nicht zu
    wirr erklaert und vielleicht kann mir da jemand weiter helfen.

    Vielen Dank schon einmal.
    Verena

    /**********Definitionsfile defs.h**************/
    
    #define MAXINT 100 /*maximale Anzahl Zahlen*/
    
    typedef struct{
      int data[MAXINT];
    }data_struct;
    
    typedef struct{
      data_struct (*process)(data_struct);
    }method_table;
    
    struct list_elem{
      method_table *pt_method_table;
      struct list_elem *next;
    };
    
    struct list_elem *first = NULL;
    struct list_elem *next = NULL;
    method_table *pt_method_table = NULL;
    
    /************Main*****************/
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "defs.h"
    
    char *error;
    int modulecounter = 0; /* Anzahl der insgesamt auszufuehrenden Module */
    char *libname[MAXLIBS]; /* MAXLIBS entspricht Anzahl der "maximal benutzbaren" */
    /* Bibliotheken evtl. spaeter hierfuer dynamische Struktur!!! */
    
    void init_libs(){
      void *filter_handle;
      int i;
      method_table (*init_filter)(void);
      method_table filter_table;
    
      struct list_elem *pointer;
    
      for (i = 1; i < modulecounter-1; i++){
        filter_handle = dlopen(libname[i],RTLD_NOW);
        if (!filter_handle){
          fputs(dlerror(),stderr);
          exit(1);
        }
    
        init_filter = dlsym(filter_handle,"init");
        if ((error = dlerror()) != NULL){
          fputs(error,stderr);
          exit(1);
        }
    
        filter_table = (*init_filter)();
    
        if (first == NULL){ /*Liste noch leer*/
          if ((first = (struct list_elem *) malloc(sizeof(struct list_elem))) == NULL)
      printf("Not enough disk space\n");
    
          first->pt_method_table = &filter_table;
          first->next = NULL;
        }
        else { /*mindestens ein Element in der Liste*/
          pointer = first;
    
          while (pointer->next != NULL)
            pointer = pointer->next;
    
          if ((pointer->next = (struct list_elem *) malloc(sizeof(struct list_elem))) == NULL)
     printf("Not enough disk space\n");
    
          pointer = pointer->next;
          pointer->pt_method_table = &filter_table;
          pointer->next = NULL;
        }   
      }
    }
    
    main(int argc, char *argv[]){
      data_struct datastruct;
      method_table filter_table;
      struct list_elem *pointer;
    
         .....
    
      /*Filter ausfuehren*/
      init_libs();
    
      while (pointer != NULL){
        filter_table = (method_table) *(pointer->pt_method_table);
        datastruct = filter_table.process(datastruct);
        pointer = pointer->next;
      }
    
         .....
    
    }
    
    /*****************Filtermodul*******************/
    
    #include 
    #include 
    #include "defs.h" 
    
    /*Filter um eingelesene Daten um 1 zu inkrementieren*/
    data_struct filter_increment(data_struct datastruct){
      int i;
    
      for(i = 0; i < MAXINT; i++)
        datastruct.data[i] = datastruct.data[i] + 1;
    
      return datastruct;
    }
    
    method_table init(){
      method_table *filterinc_table;
      filterinc_table = (method_table *) malloc(sizeof(method_table));
    
      filterinc_table->process = filter_increment;
    
      return *filterinc_table;
    }
    


  • Hat sich erledigt.
    Die Variable filter_table musste global sein.
    Hab ich verpeilt. Typisch fuer mich. Naja.



  • Also geht jetzt alles?

    Brauchst keine Hilfe mehr?



  • Das Problem ist erstmal geloest. Hab jetzt weiter unten irgendwo Segentation Fault. Da muss ich erstmal schauen, woran es liegen kann. Segmentation Fault hab ich meistens auch selbst raus bekommen. Vorher die Fehlermeldung mit Illegal Instruction fand ich nur etwas irritierend, hatte ich noch nie vorher und dass es an dieser Variable lag, weil sie nicht global war, haette ich auf Anhieb nicht gedacht.
    Aber vielen Dank trotzdem.



  • Das Problem ist erstmal geloest.

    Super.

    Aber vielen Dank trotzdem.

    immer gern 🙂


Anmelden zum Antworten