Singleton w dll

patryj1083
  • Rejestracja:prawie 13 lat
  • Ostatnio:ponad 6 lat
  • Postów:102
0

Witam
próbuję dodać klasę Singleton do pliku DLL. Niestety dostaję informację o takim będzie:

Kopiuj
error C2491: 'HE::Singleton<T>::~Singleton' : definition of dllimport function not allowed
error C2491: 'HE::Singleton<T>::destroySingleton' : definition of dllimport function not allowed
error C2491: 'HE::Singleton<T>::getSingletonPtr' : definition of dllimport function not allowed
error C2491: 'HE::Singleton<T>::Singleton' : definition of dllimport function not allowed
 

i nie mam pojęcia gdzie jest błąd. I przy okazji czy wykorzystywanie w programie singletonów to dobry pomysł?

Kopiuj
#ifdef DLL_EXPORTS
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif

//Singleton.h
namespace HE
{

	template<typename T>
	class DLL_API Singleton
	{

	public:
		Singleton();
		virtual ~Singleton();
		static T& getSingleton()
		{
			assert(mpInstance); return (*mpInstance);
		}
		static T* getSingletonPtr();
		static void destroySingleton();
		
	protected:
		static T* mpInstance;
	};

}
//Singleton.cpp
using namespace HE;

template<typename T> T* Singleton<T>::mpInstance = nullptr;
template<typename T> 
T*  Singleton<T>::getSingletonPtr()
{
	return mpInstance;
}
...
 
PR
  • Rejestracja:około 11 lat
  • Ostatnio:5 dni
  • Lokalizacja:Pomorskie (Stare Kabaty)
0

Może zdefiniuj ciało tych funkcji? :- )
Co do singletonów, to odpowiedź brzmi - zależy do czego.

edytowany 1x, ostatnio: Proxima
patryj1083
  • Rejestracja:prawie 13 lat
  • Ostatnio:ponad 6 lat
  • Postów:102
0

Mam zdefiniowane ciała. Po prostu nie chciało mi się wszystkiego kopiować. :)

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:3 minuty
3

Problemem jest DLL_API (AKA: _declspec(dllexport)).
Dla szablonu jest to bezsensu, bo sam szablon nie generuje żadnego kodu ani zmiennych, więc dll-ka nie ma co eksportować!
Jedynie specjalizacja szablonu mogłaby to zrobić!


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
Azarien
ściślej: architektura DLL nie pozwala na eksportowanie szablonów. teoretycznie byłoby to (z trudem) wykonalne.
patryj1083
@Azarien "teoretycznie" czyli jak? Pytam tak z ciekawości.
Azarien
na podobnej zasadzie co działało (nie działało) niesławne słowo export w C++, albo jak rozwiązano eksportowanie typów generycznych z .DLLi pod .NET - w obu przypadkach mamy do czynienia z kodem pośrednim, z którego linker albo runtime generuje kod wynikowy...
Azarien
pisząc "byłoby wykonalne" mam na myśli że NIE JEST wykonalne, ale gdyby napisać własny kompilator, linkera i loadera DLL-i, to możnaby taki ficzer przewidzieć.
patryj1083
Dzięki za wyjaśnienie.
Endrju
  • Rejestracja:około 22 lata
  • Ostatnio:ponad rok
0

Musisz wygenerować konkretną instancję szablonu. W przypadku takiego generycznego singletonu w bibliotece musisz mieć singelton opakowujący konkretną klasę. Nie da się w bibliotece zamknąć "kodu" szablonu. Szablon musi być i tak znany podczas kompilacji. (Słowo kluczowe export zostało usunięte z C++, tylko jedna implementacja to obsługiwała - EDG)

Nagłówek:

Kopiuj
template <typename T>
class DLL_API X {
  // ...
};

extern template class X<int>;

Plik źródłowy:

Kopiuj
template class DLL_API X<int>;

Miałem dokładnie taki sam problem (singleton w bibliotece współdzielonej, ogólnie miałem z tym dziwne problemy) i tak go rozwiązałem.

Poza tym u Ciebie getSingletonPtr nie może być w pliku źródłowym, wszystko musi być w pliku nagłówkowym.


"(...) otherwise, the behavior is undefined".
edytowany 4x, ostatnio: Endrju

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.