2011-07-12 73 views
3

假設我有這樣的模板類:模板類與整個使用靜態數據成員DLL/SO

template <class T> 
class Queue 
{ 
public: 
    static int Size; 
}; 

template <class T> int Queue<T>::Size = 0; 

我導出D.dll函數使用隊列作爲一個參數:

void ChangeQueueSize(Queue<int>& q) 
{ 
    q.Size = 100; 
} 

然後我使用該出口在A.exe時功能:

Queue<int> q; 

q.Size = 10; 

ChangeQueueSize(q); 

int updatedSize = q.Size; 

由於隊列類是從類模板在2工程中的生成ts,實際上有2個代碼副本,以及靜態數據成員。

所以調用ChangeQueueSize在這裏不會真的改變隊列的大小,它只是更新另一個類的靜態成員,它恰好具有相同的類名。

我們可以做些什麼來解決這個問題?
gcc中的弱符號能夠解決這個問題嗎?
非常感謝。

回答

4

您不能以您想象的方式將模板放入庫中。您只能將實際的,實例化的類定義放入庫中。

模板本質上是一個代碼生成工具,您只能將生成的代碼放入庫中。

你可能想使用顯式模板實例使編譯器生成的代碼,並採取靜態成員定義頭:

// Header, shipped to clients 
template <class T> 
class Queue 
{ 
public: 
    static int Size; 
}; 

// Library source code: 
template <typename T> int Queue<T>::size = 0; 

template class Queue<int>; 

現在編譯源文件到庫;這將包含靜態成員變量Queue<int>::size的實例。

請注意,您的消費者只能使用T = int類中的實例,否則他們無法訪問靜態成員(即他們必須自行提供)。

+0

謝謝,我可以使用declspec(dllexport)/ declspec(dllimport)以及您的方式來「導出」隊列因此DLL和客戶端共享代碼。你有沒有關於如何在Linux中實現這個想法,似乎沒有這樣的機制。 –

+0

你不需要Linux上的'declspec'。只要讓它成爲一個在Linux上什麼都不做的平臺條件宏。 –

+0

我還沒有嘗試過,但是然後,SO和可執行文件將有自己的隊列副本,你真的認爲它工作正常嗎? –

相關問題