2016-03-02 33 views
3

我有用C++包裝的C++ dll。該DLL在我的C#項目中調用。DLL中的單例被破壞

在我的包裝功能,我叫了很多單身的,他們的設置如下:

ComponentManager &ComponentManager::_cmpManager() 
{ 
    static ComponentManager ONLY_ONE; 
    return ONLY_ONE; 
} 

上述功能是我的ComponentManager類中的靜態函數。 下面是具體的問題:

bool createNewEntity(char *c) 
{ 
    if (ComponentManager::_cmpManager().nameAvailable(c)) 
    { 
     Entity e(c); 
     Transform t; 
     ComponentManager::_cmpManager().addComponent(c, t); 
     SceneNode sc(CMP_MANAGER2.getComponent<Transform>(c)); 
     SCENE_MANAGER.addSceneNode(sc, e.entityName); 
     return true; 
    } 
    return false; 
} 

本質上講這確實是單有一個哈希地圖與一鍵式字符串,這個功能檢查,看看是否這個鍵已經存在。行爲總是返回真實的。當我使用類型componentManager的全局對象而不是單身人士時,它的行爲正確,所以有些東西告訴我單身人員一直在離開範圍並刪除自己。另外如果我在應用程序的exe中使用單例而不是dll,它的行爲是正確的。所以我有2個問題,

  1. 有沒有辦法讓我的單身人士超出範圍?如果 不是。
  2. 有沒有另外一種方法設置單身不能刪除 離開範圍之後呢?
+2

爲什麼你認爲物體被破壞?如果函數總是返回true,則表示該名稱可用(如果ComponentManager是新構造的,則不太可能)。另外,你的createNewEntity函數實際上並沒有創建任何東西。要麼你的代碼很奇怪(恕我直言),或者你省略瞭解你的問題的重要部分。 – Rumburak

+0

您是否禁用了複製構造函數?是否有可能將返回的單例賦值給變量而不是引用? – Galik

+0

我將編輯我的問題以獲取更多信息。函數createNewEntity被簡化。當我使用類型爲componentManager的對象時,該函數在獲取名稱時返回false。 –

回答

0

C++ 靜態關鍵字是從C#靜態有點不同。 查看https://msdn.microsoft.com/en-us/library/y5f6w579.aspx的描述。

在第2條中它說:2.當你在一個函數中聲明一個變量時,static關鍵字指定該變量保持它在該函數調用之間的狀態。

試着聲明你的靜態方法不在方法內,而是在類範圍內(如上面引用中的第3項)。

3.當您在類聲明中聲明數據成員時,static關鍵字指定成員的一個副本由類的所有實例共享。靜態數據成員必須在文件範圍內定義。您聲明爲const static的完整數據成員可以有一個初始化程序。

您還需要在文件範圍聲明該靜態成員。

它爲什麼在它不在dll中時有效 - 它不完全清楚。可能是連接器的一種特殊行爲。如果在dll中聲明瞭類,它可能會嘗試每次都實例化類,並且每次您函數內部的靜態都是新的。但是,如果class在exe文件中,那麼每次當你調用你的方法_cmpManager()時它總是訪問同一個類的實例。

只是我的兩分錢:-)。