2010-02-17 13 views
8

Ambiente: Visual Studio 9, C++ senza estensioni gestite.DLL e modello template completamente specializzato

Ho una libreria di terze parti che esporta una classe template completamente specializzata MyClass<42> definita in MyClass.h. Viene compilato in un helper loader .lib e un file .dll. Il file .lib contiene il codice compilato per questa specializzazione e i simboli necessari. Il MyClass.h assomiglia a questo:

template<UInt D> 
class MyClass { 
public: 
    MyClass() {...}; 
    virtual ~MyClass() {}; 
} 

Ora mi piacerebbe utilizzare questa libreria. Se includo MyClass.h in un Client.cpp e poi lo compilo, otterrò la seconda copia di questi simboli nel file Client.obj. Posso sbarazzarmi di questi simboli definendo tutti i membri di quella specializzazione come "extern". Il mio Client.cpp assomiglia a questo:

#include <ThirdParty/MyClass.h> 

extern template class MyClass<42>; 
extern template MyClass<42>::MyClass<42>(); 
extern template MyClass<42>::~MyClass<42>(); 

void MyFunction(MyClass<42>& obj) {...} 

Il problema è che non riesco a sbarazzarmi del distruttore virtuale in questo modo. Per il distruttore virtuale ottengo un errore LNK2005 quasi standard:

ThirdPartyd.lib(ThirdPartyd.dll) : error LNK2005: 
    "public: virtual __thiscall MyClass<42>::~MyClass<42>(void)" 
    ([email protected][email protected]@@[email protected]) already defined in Client.obj 

Cosa devo fare?

risposta

4

Sembra che per i metodi virtuali, è necessario definirli come sia extern e __declspec(dllimport) allo stesso tempo:

extern template __declspec(dllimport) MyClass<42>::~MyClass<42>(); 

Questo ha reso il mio linker abbastanza felice di legare il mio codice correttamente.

Sarei molto contento se qualche esperto ha descritto il motivo per cui è così, o almeno ha indicato un articolo che spiega questo caso.

1

Credo che Visual Studio utilizzi la specializzazione dei modelli in DLL per alcuni costrutti STL. string viene in mente,

ho dato un'occhiata veloce al file di intestazione, e sembra che sta usando

__declspec(dllimport) 

sulla dichiarazione di un gruppo di specializzazioni. Tuttavia, non sembra che lo faccia per l'intera classe.

Da this discussion sembra che sia possibile dichiarare l'intera classe come esportata, ma non dice come.

Ci scusiamo per la risposta non così completa, ma speriamo che questo possa aiutarti a esplorare altri luoghi.

+0

+1 Sono contento che tu abbia dato un suggerimento così piccolo. – liori

Problemi correlati