Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Problema esportazione in DLL function template
Forum - C/C++ - Problema esportazione in DLL function template

Avatar
quello che non so come si chiama (Normal User)
Rookie


Messaggi: 37
Iscritto: 08/01/2013

Segnala al moderatore
Postato alle 19:33
Martedì, 08/01/2013
Ciao a tutti, come da titolo mi trovo di fronte a questo problema:
Sto realizzando una Dll che ha varie classi e riesco ad esportarle tutte senza problemi, però non risultano esportate le funzioni template...
Mettiamo che ho una classe del tipo:
Codice sorgente - presumibilmente C/C++

  1. class __declspec(dllexport) MemoryManager
  2. {
  3. public:
  4.     template<typename Type>
  5.     static Type* AllocMemory(int quantita)
  6.     {
  7.         //Corpo funzione
  8.     }
  9.     //Altri metodi
  10.     //...
  11. };


Premetto che il corpo l'ho messo nella dichiarazione del metodo perché se lo mettevo nel .cpp il linker mi bestemmiava in faccia e se qualcuno mi sapesse dire come fare a metterlo nel .cpp gliene sarei grato, ma questo è un altro problema...

Tornando al problema, quando compilo non mi dice nulla e compila correttamente.
Quando vado ad utilizzare il metodo in un programma, chiaramente dopo aver linkato il .lib che la compilazione precedente mi aveva dato in output e dopo aver definito la classe con il __declspec(dllimport) eccetera, il linker mi dice che non lo trova.
Le altre classi e metodi che ho esportato riesco ad utilizzarle, per cui suppongo che non sia un errore nelle dichiarazioni.
Ho provato a guardare quali metodi avessi all'interno della Dll aprendola con il DependencyWalker(non so se sia lo strumento più adatto) e lì ho trovati tutti, tranne, appunto, le funzioni template.

Per togliermi ulteriori scrupoli ho chiesto al compilatore di generarmi anche gli .asm ed ho notato, siccome anche all'interno della Dll richiamo alcune funzioni template da me scritte tipo quella di sopra, che la definizione di questi metodi non era nel MemoryManager.asm, ma negli .asm delle classi che utilizzavano tali metodi(per cui definiti più volte in base ai tipi che passavo al template).
Una deduzione che ho fatto è che se la funzione deve essere definita ogni volta che la chiamo con un tipo diverso è abbastanza impossibile che me la possa esportare in un solo corpo nella Dll.
Se tale deduzione ha senso, è possibile comunque non dovere distribuire gli header delle classi senza dover fornire anche l'implementazione delle funzioni template, restando sempre sotto la "soluzione" Dll anziché passare ad una libreria statica.

PS: Uso VC++ 2010

Spero di essere stato abbastanza chiaro.
Grazie.

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 21:10
Martedì, 08/01/2013
Lo standard C++ in teoria prevede la compilazione separata dei template, ma nessun compilatore che io conosca implementa questa cosa.(ed è per questo che il linker si incazza ed i template vanno dichiarati nei file .h)

( Questo post riassume la questione meglio di quanto sappia fare io: http://msmvps.com/blogs/vandooren/archive/2008/09/24/c-key ... )

Piuttosto avviene quanto hai giustamente notato, cioè che l'espansione dei template genera N versioni dello stesso codice.

Questo è uno dei peggiori difetti del C++ ed è noto come "template explosion".
Un workaround potrebbe essere quello di esportare in DLL dei normali metodi che chiamano una versione specializzata di quel template, facendo quindi un wrapper che forza il compiler a generare alcune specializzazioni.
Questo ovviamente implica che la DLL potrà esportare un numero limitato di specializzazioni e perderai la flessibilità originale del template.


Non so se esistono soluzioni totali al problema, in caso se ne trovi qualcuna mi interesserebbe sapere come realizzarla :)

Ultima modifica effettuata da TheKaneB il 08/01/2013 alle 21:14
PM Quote
Avatar
quello che non so come si chiama (Normal User)
Rookie


Messaggi: 37
Iscritto: 08/01/2013

Segnala al moderatore
Postato alle 19:07
Lunedì, 14/01/2013
Mi scuso per risponderti soltanto adesso e ti ringrazio per la risposta, comunque sono poco fiducioso riguardo una possibile soluzione, se dovessi trovarla ti farò sapere.
Grazie di nuovo

PM Quote