Pour l'instant je suis arrivé a une solution "médiane"
Le problème que j'ai est que l'on ne peut pas vraiment exporter un template :
Code :
- template <class A, class B>
- class DECLSPECIFIER_DLL TheTemplatedSingleton
- : Singleton <TheTemplatedSingleton<A,B>> // magie!
- {
- ...
- }
|
ça build bien la Dll, mais du point de vu de l'exe :
Code :
- #include "TestSingletonMain.h"
- int main ()
- {
- int ij;
- TestSingletonMain* m = new TestSingletonMain();
- TestSingletonDll* d = new TestSingletonDll();
- cout << " courant : "<<d->Next<int,int>()<<endl;
- cout << " courant : "<<d->Next<int,int>()<<endl;
- //cout<< " courant : "<<Singleton<TheTemplatedSingleton<int,int>>::Get().Prochain()<<endl;
- cout<< " courant : "<< TheTemplatedSingleton<int,int>::Get().Prochain() <<endl;
- cin >> ij;
- }
|
par contre le build ne finit pas, et débouche sur une erreur à l'étape de link :
Code :
- 1>TestSingletonMain.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class TheTemplatedSingleton<int,int> & __cdecl TheTemplatedSingleton<int,int>::Get(void)" (__imp_?Get@?$TheTemplatedSingleton@HH@@SAAAV1@XZ) referenced in function _main
- 1>TestSingletonMain.obj : error LNK2019: unresolved external symbol "public: int __thiscall TestSingletonDll::Next<int,int>(void)" (??$Next@HH@TestSingletonDll@@QAEHXZ) referenced in function _main
|
bien sur si j'enlève les export/import :
Code :
- template <class A, class B>
- class /*DECLSPECIFIER_DLL*/ TheTemplatedSingleton
- : Singleton <TheTemplatedSingleton<A,B>> // magie!
- {
- ...
- }
|
ça compile bien mais je me retrouve au problème initiale : duplication des instances :
Code :
- Nouveau Singleton !!!
- courant : 1
- courant : 2
- Nouveau Singleton !!!
- courant : 1
|
finallement je suis obliger de simuler l'exportation du template pour passer l'étape de link.
Cela se fait en declarant et en exportant les différentes instance de template que l'on va utiliser :
TheTemplatedSingleton.cpp:
Code :
- #include "TheTemplatedSingleton.h"
- template <class A, class B>
- TheTemplatedSingleton<A,B>::TheTemplatedSingleton (): m_Cur (0)
- {
- cout<<endl<<"Nouveau Singleton<"<<typeid(A).name()<<","<<typeid(B).name()<< "> !!!"<<endl<<endl;
- }
- template <class A, class B>
- int TheTemplatedSingleton<A,B>::Prochain()
- {
- return ++m_Cur;
- }
- EXPIMP_TEMPLATE_DLL template class DECLSPECIFIER_DLL TheTemplatedSingleton<int,int>;
- //EXPIMP_TEMPLATE_DLL template class DECLSPECIFIER_DLL Singleton<TheTemplatedSingleton<int,int>>;
|
et
TestSingletonDll.cpp
Code :
- #include "TestSingletonDll.h"
- template<class A, class B>
- int TestSingletonDll::Next()
- {
- //return Singleton<TheTemplatedSingleton<A,B>>::Get().Prochain();
- return TheTemplatedSingleton<A,B>::Get().Prochain();
- }
- EXPIMP_TEMPLATE_DLL template DECLSPECIFIER_DLL int TestSingletonDll::Next<int,int>();
|
En ce cas je peut builder l'executable car celui-ci n'utilise que l'instance du singleton template :
Code :
- TheTemplatedSingleton<int,int>
|
que je viens d'exporter explicitement (cette instance de TheTemplatedSingleton pour les type <int,int> )
et on peut voir que cela fonctionne effectivement :
Code :
- Nouveau Singleton<int,int> !!!
- courant : 1
- courant : 2
- courant : 3
|
Donc content ?
en fait NON car comme on le vois si on veut exporter un template, qui est singleton afin de n'avoir qu'une seul instance (par instance de template!) partager entre la (les) Dll et l'exécutable, il faut exporter explicitement TOUTES les instances possible du template que l'on serai a même d'utiliser au niveau de l'exécutable ... bref plutôt contraignant ...
Existe t'il une solution/une parade a cela ? je suis preneur de toute information en ce sens 
Message édité par el_trex le 07-08-2008 à 10:46:54