2012-04-11 111 views
2

我試圖創建模板工廠類,導出一個創建方法:dllexport'ing靜態模板方法

template <typename T> 
class ClassFactory 
{ 
    _declspec(dllexport) static void* Create() 
    { 
     return new T; 
    } 
}; 

class Foobar : ClassFactory<Foobar> 
{ 
    std::string foo; 
}; 

此代碼編譯就好了,但我沒有看到在出口表時什麼我看DUMPBIN /出口

下面的代碼創建出口的輸出()正確:

class ClassFactoryBase 
{ 
    _declspec(dllexport) virtual void* Create() = 0; 
}; 

template <typename T> 
class ClassFactory : ClassFactoryBase 
{ 
    void* Create() 
    { 
     return new T; 
    } 
}; 

class Foobar : ClassFactory<Foobar> 
{ 
    std::string foo; 
}; 

不過,我需要創建()是靜態的。爲什麼樣本2有效,而樣本1沒有?有沒有辦法導出靜態模板方法?

+0

您的編譯器不支持模板的外部鏈接。幾乎沒有人會支持它的模塊。導出無法工作,您必須將模板定義移動到頭文件中。 – 2012-04-11 11:00:49

回答

0

無法從DLL中導出模板方法,因爲非實例化的模板方法甚至沒有編譯。你的例子對DLL本身並沒有太多的幫助,頭文件就是那個讓所有的東西都能正常工作的頭文件。

+0

我不是在尋找ClassFactory :: Create()被導出。我想要導出ClassFactory :: Create()。我的理解是,該方法應作爲Foobar課程的一部分進行編譯。我錯過了什麼嗎? – alexlesh 2012-04-11 17:47:10

2

編譯器發現Create()函數從未被調用,因此它不會爲其生成任何代碼。要使它工作,你需要明確實例化你的模板,像這樣:

template class ClassFactory<Foobar>; 

只需將此行添加到您的源代碼。現在編譯器會生成這個函數的代碼並導出它。欲瞭解更多信息,請參閱此MSDN文章 - Explicit Instantiation (C++)

要回答您的其他問題,爲什麼示例2的作品和示例1沒有,讓我們仔細看看派生類Foobar。在這個類中有一個虛函數,所以編譯器必須生成一個vtable。要填充vtable,編譯器需要知道Create()的地址,這是從基類模板隱式實例化的時候。根據要求生成此函數的代碼並將其導出到DLL。這就是爲什麼示例2有效。