libltdl und DLLs



  • Hallo!

    Ich arbeite gerade an einem Projekt, das zur Laufzeit auf Benutzeranfrage ein Modul nachlädt. Um portabel zu sein benutze ich libltdl. Unter Linux funktioniert auch alles perfekt: Die .so wird geladen, die Symbole gefunden. Wenn ich das ganze aber mit Mingw compile geht das nicht mehr: Die .dll wird zwar geladen, aber die Sympole werden nicht gefunden. Ich hab dann man mit nm nachgeschaut, ob die Symbole in der DLL sind. Da habe ich festgestellt, das allen exportierten Symbolen - anders als unter Linux - ein _ voransteht. Also kann libltdl das Symbol gar nicht finden. Wie bekomm ich also das _ weg? Ich definiere die exportierten Funktionen folgendermaßen:

    extern "C"
    {
      __declspec(dllexport) char* my_func(void)
      {
        // Code...
      }
    }
    


  • Achja, natürlich habe ich ein

    #define my_func modulename_LTX_my_func
    

    wie von libltdl gefordert.



  • Das "" bekommst Du weg, indem Du eine def-Datei für die DLL erstellst und dort jede Funktion einträgst, die Du exportieren willst.
    Siehe:
    http://msdn.microsoft.com/library/en-us/vccore/html/_core_Export_from_a_DLL_Using
    ..DEF_Files.asp



  • Auch mit so einer .def-Datei ändert sich nix.



  • Also ich hab jetzt 'ne Lösung:

    Undokumentierterweise benötigt libltdl unter Windows kein modulename_LTX_ vor der exportierten Funktion. Also werden meine Funktionsdefininionen jetzt ziemlich hackisch:

    extern "C" 
    {
    #ifdef DLL_EXPORT
    # ifdef LT_SCOPE
    #  undef LT_SCOPE
    # endif
    # define LT_SCOPE __declspec(dllexport)
    #else
    # define LT_SCOPE
    # define process gbo_LTX_myfunc
    #endif
    
      LT_SCOPE char* myfunc()
      {
        // Code...
      }
    }
    

    Wegen der oben beschriebenden Sache mit dem _ vor den exportierten Funktionen habe ich einfach libltdl gehackt:

    /* --- LOADLIBRARY() INTERFACE LOADER --- */
    
    #ifdef __WINDOWS__
    
    /* dynamic linking for Win32 */
    
    /* [...] */
    
    static lt_ptr
    sys_wll_sym (loader_data, module, symbol)
         lt_user_data loader_data;
         lt_module module;
         const char *symbol;
    {
      lt_ptr      address  = GetProcAddress (module, symbol);
    
      if (!address) /* Try again with a leading underscore. */
                   /* Hacked by Josephine. Modifications   */
        {         /* are public domain, because trivial.  */
          size_t len = strlen(symbol) + 1;
          char* sym = malloc(len);
          sym++; memcpy(sym, symbol, len);
          sym--; sym[0] = '_';
          address = GetProcAddress (module, sym);
        }
    
      if (!address)
        {
          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
        }
    
      return address;
    }
    
    /* [...] */
    
    #endif /* __WINDOWS__ */
    

    Immer dies Extrawurst für Windows.. 👎



  • Mit Visual C++ 2005 wäre das meines Wissens nicht passiert mit dem Unterstrich. 😉


Anmelden zum Antworten