2012-05-12 249 views
4

我有靜態成員的靜態庫。這個庫靜態鏈接到主應用程序和它的一個插件。看起來像初始化主(應用程序)和DLL(插件)中的靜態變量。靜態庫的靜態成員

問題:如何在動態庫加載時避免靜態變量重新初始化。或者我可能錯過了一些簡單的東西?

更多信息:

這是簡單的靜態庫,包含靜態成員,它的getter和setter:

orbhelper.h

class ORBHelper { 
    static std::string sss_; 
public: 
    static std::string getStr(); 
    static void setSTR(std::string str); 
}; 

orbhelper.cpp

std::string ORBHelper::sss_ = "init"; 

static std::string ORBHelper::getStr() 
{ 
    std::cerr << "get " << sss_.c_str() << std::endl; 
    return sss_; 
} 
static void ORBHelper::setSTR(std::string str) 
{ 
    sss_ = str; 
    std::cerr << "set " << sss_.c_str() << std::endl; 
} 

該庫在main.cpp中使用,也在另一個動態庫中使用,即在main中加載。 在main.cpp中,我設置了靜態字符串,並將其放入了一個動態庫函數中,我希望得到它。

設置靜態變量主:

的main.cpp

... 
ORBHelper::setStr("main"); 
std::cerr << ORBHelper::getStr().c_str() << std::endl; //prints 'main' 
//then loading library 
... 

然後讓DLL中的變量值:

hwplugin.cpp

... 
std::cerr << ORBHelper::getStr().c_str() << std::endl; //prints 'init' instead of 'main' 
... 

貌似靜態變量已經初始化twi CE。第一次 - 在main.cpp之前,第二次 - 當加載動態庫時。具有靜態類的靜態庫鏈接到主應用程序和動態庫。

P.S.在我的問題中,太多的單詞'static',我知道=)

+0

如果你靜態鏈接,你可能會得到兩個變量的實例,一個在exe中,另一個在DLL中。 –

+0

我查了一個變量的地址(printf(「%p」,&sss);),發現它是同一個變量。 – uni

+2

我最近有同樣的問題(http://stackoverflow.com/q/105205​​87/509868) ;有兩個可用的解決方案(1:將靜態庫轉換爲(第二個)DLL;或者2:將函數添加到現有的DLL中,以初始化靜態庫中的有問題的東西) – anatolyg

回答

0

是的,你有兩個輔助類實例。

該DLL應該鏈接到可執行文件,該文件將靜態類鏈接到該可執行文件中,並使用該可執行文件來解析該輔助類。不要將DLL鏈接到靜態庫,而是將其鏈接到可執行文件本身。

+0

你不能這樣做,你會在構建dll的時候出現鏈接器錯誤 –

+0

我在每一個函數裏都添加了printf(「%p」,&sss_);幫助者的每一次打印相同的地址。這不是說只有一個助手實例嗎? – uni

+0

嗯...可能,但它是仍然運行兩次,即使符號映射到相同的內存地址的靜態初始值設定項。 –