2012-12-04 70 views
2

我有一個C++類庫項目,該項目通常由其他C++項目使用。爲了能夠使用我的類庫項目中的類,我寫了一個頭文件中像下面在類庫項目中創建模板類C++

#pragma once 
#ifdef MYLIB 
# define MYLIB_EXPORT __declspec(dllexport) 
#else 
# define MYLIB_EXPORT __declspec(dllimport) 
#endif 

沒問題給出直到我要創建我的類庫項目中模板類的例子。問題是我無法導出我的模板類。

MyClass.h

template<class T> 
class MYLIB_EXPORT MyClass 
{ 
    void myMethod(); 
    // ... 
} 

template<class T> 
void MyClass::myMethod() 
{ 
    // ... 
} 

在這種情況下,我得到compilaton錯誤說: 「不準dllimport的函數的定義」。我知道是什麼原因導致這個問題,我理解它。其他使用我的類庫項目的項目將MYLIB_EXPORT關鍵字轉換爲__declspec(dllimport)。因此,他們期望在DLL中定義MyClass的方法。但是,編譯器會在頭文件中看到定義。

如何克服這種情況,並能夠導出我的類庫項目中定義的模板類?

回答

4

無法直接編譯未經實例化的模板 - 它們是代碼生成器,所以它們實際上只在實例化時才轉換爲二進制指令;由於這個原因,你不能以「二進制形式」輸出一個模板,就好像它是一個「常規」函數/類(另一方面,至少在理論上你可以導出一個模板的實例化)。

長話短說:只需將庫中的模板留在圖書館客戶端即可。

請注意,這就是爲什麼您在標題中保留模板的原因,並且您通常不會在.cpp文件中將它們的實現分開。

0

只需刪除模板類上的MYLIB_EXPORT聲明。然後,您可以在類之外定義類函數(但仍在*.h*.hpp頭文件中)。

MyClass.h

template <typename T> 
    class MyClass // MYLIB_EXPORT removed 
    { 
     void myMethod(); 
     // ... 
    }; 

    template <typename T> 
    void MyClass<T>::myMethod() 
    { 
     // ... 
    } 

我得到了這個問題。很長一段時間後,我意識到刪除MYLIB_EXPORT會修復它。希望這個答案可以節省時間給他人:-)