[mingw]: Linker sagt "Cannot export..." bei Verwendung von Template-Funktionen in Klasse



  • Hallo Forum,

    nach Umstellung auf die neueste Version von MinGW erhalte ich beim Bauen meiner Lib einen Fehler vom Linker, den ich nicht beseitigen kann. Der Fehler tritt auf bei Verwendung von Template-Funktionen einer Klasse. Zur Erklärung habe ich mal folgendes Beispiel-Szenario aufgebaut:

    --- MyClass.hpp ---
    
    #include <vector>
    
    class __declspec(dllexport) MyClass {
    
    public:
      template <typename Pred>
      size_t enumInts(Pred pred) {
        size_t count = _myColl.size();
        for(size_t i = 0; i < count; ++i)
          if(!pred(_myColl[i]))
            return i;
        return count;
      }
    
    private:
      std::vector<int> _myColl;
    };
    
    --- ClassUser.hpp ---
    
    #include "MyClass.hpp"
    
    class __declspec(dllexport) ClassUser {
    
    public:
      int foo();
    
    private:
      MyClass _my;
    };
    
    --- ClassUser.cpp ---
    
    #include <functional>
    
    #include "ClassUser.hpp"
    
    namespace {
    
    struct MyPred: public std::unary_function<int, bool> {
      bool operator()(int i) const {
        return i > 10;
      }
    };
    
    }
    
    int ClassUser::foo() {
      return _my.enumInts(MyPred());
    }
    

    Beim Bauen erhalte ich hiermit vom Linker die Fehlermeldung:

    Cannot export _ZN7MyClass8enumIntsIN12_GLOBAL__N_16MyPredEEEjT_: symbol not found
    

    Man beachte, was da angemeckert wird: Die Instanziierung von MyClass::enumInts() in ClassUser::foo()!!

    Ich hample jetzt schon länger an diesem Code herum, ohne den Fehler beseitigen zu können. Immerhin habe ich festgestellt, dass er unter zwei Bedigungen nicht auftritt:

    - Falls "__declspec(dllexport)" vor MyClass entfernt wird.
    - Oder falls der Funktor Pred nicht in einem anonymen Namespace liegt.

    Das erste ist auf keinen Fall eine Option für mich, da die reale Klasse noch jede Menge (nicht-Template-)Funktionen enthält, die aus der DLL exportiert werden sollen.

    Das zweite mag ich eigentlich auch nicht, da dies ja bei allen Verwendungen der Template-Funktion beachtet werden muss, und Benutzer meiner Lib sonst diesen schwer durchschaubaren Fehler erhalten.

    Hat jemand eine Idee, wie ich ohne die obigen Workarounds weiter komme? Oder vielleicht gar eine Erklärung für den Fehler?

    Visual Studio 2005 baut die Lib übrigens ohne Probleme.

    gcc -v: 4.4.0
    ld -v: 2.19.1

    Stefan.


Anmelden zum Antworten