Warnung: Vererbung von Nicht-DLL-Schnittstelle



  • Ich benutze VS2010 und habe eine Klasse NonCopyable ohne __declspec. Scheint mir auch nicht nötig, da die einzige Methode (Defaultkonstruktor) inline ist.

    Nun erhalte ich aber beim Ableiten von Klassen, die selbst mit__declspec(dllexport) gekennzeichnet sind, ständig folgende Warnung:

    warning C4275: class 'NonCopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'XY' verwendet

    Warum muss ich eine DLL-Schnittstelle haben, wenn die Methoden inline sind? Kann man die Warnung sinnvoll beheben oder soll ich sie einfach deaktivieren?


  • Mod

    Steht alles in der Beschreibung:
    http://msdn.microsoft.com/de-de/library/3tdb471s(v=vs.80).aspx

    Für noncopyable ist das natürlich kein Problem weil die Klasse keine Member hat.
    Aber hätte sie welche, könnte eine abgeleitete KLasse in der EXE die DLL-Klasse eben nicht korrekt behandeln. Das ist der Hintergrund dieser Warnung.

    Ich würde nich versuchuen diese Mledung zu umgehen.
    Du kannst das "noncopyable" auch anders erreichen 😉



  • Martin Richter schrieb:

    Für noncopyable ist das natürlich kein Problem weil die Klasse keine Member hat.
    Aber hätte sie welche, könnte eine abgeleitete KLasse in der EXE die DLL-Klasse eben nicht korrekt behandeln. Das ist der Hintergrund dieser Warnung.

    Vielen Dank für die Erklärung. Schade, dass hier VS die Gefahrlosigkeit einer leeren Klasse nicht erkennt.

    Martin Richter schrieb:

    Ich würde nich versuchuen diese Mledung zu umgehen.
    Du kannst das "noncopyable" auch anders erreichen 😉

    Ja, jedes Mal von Neuem Kopierkonstruktor und Zuweisungsoperator privat definieren. Tolle Lösung, genau das will ich mit NonCopyable ja vermeiden.

    Kann ich die Warnung wenigstens lokal deaktivieren? Es scheint, als hätte

    #pragma warning(push)
    #pragma warning(disable: 4275)
    
    class NonCopyable {...};
    
    #pragma warning(pop)
    

    keinen Einfluss, da das Ableiten an anderer Stelle geschieht. Gibt es keinen anderen Weg, als die Warnung global abzuschalten?


  • Mod

    Nein. Du kannst auch eine gemeinsame entsprechende Klasse bauen, die Du exportierst.



  • mMn. spricht auch nix dagegen die Klasse NonCopyable einfach zu exportieren.
    Es ist zwar nicht nötig, schadet aber auch nicht, und dann sollte der Compiler Ruhe geben.



  • Ich verwende die Klasse in einer Header-Only-Library. Da will ich möglichst vermeiden, dass der Benutzer etwas konfigurieren muss.

    Wäre folgendes ein gangbarer Weg, um trotzdem portabel zu bleiben? Oder gibts da Probleme, wenn man gar keine DLL erstellen möchte?

    #if (defined(_WIN32) || defined(__WIN32__))
    	#define MY_API __declspec(dllexport)
    #else
    	#define MY_API
    #endif
    
    class MY_API NonCopyable { ... };
    


  • Grundsätzlich immer __declspec(dllexport) ist nicht der richtige Weg. __declspec(dllexport) sollte nur beim Bauen der DLL verwendet werden, beim Bauen von anderem Code der diese DLL verwendet musst du entsprechend __declspec(dllimport) verwenden.

    Spendiere der DLL doch ihre eigene "MyDllNonCopyable" Klasse. Dann ist die unabhängig von deiner Header-Only Lib und alles ist gut.


Anmelden zum Antworten