【问题标题】:Singleton in DLL being destroyedDLL中的单例被破坏
【发布时间】:2016-03-02 06:24:29
【问题描述】:

我将 C++ 包装在 C dll 中。该 dll 在我的 C# 项目中被调用。

在我的包装函数中,我调用了很多单例,它们的设置如下:

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;
}

本质上它的作用是单例有一个带有键类型字符串的哈希映射,这个函数检查这个键是否已经存在。行为总是返回 true。当我使用 componentManager 类型的全局对象而不是单例时,它的行为正确,所以有些事情告诉我单例不断离开范围并删除自己。此外,如果我在应用程序 exe 而不是 dll 中使用单例,它的行为正确。所以我有两个问题,

  1. 有没有办法防止我的单身人士超出范围?如果 不是。
  2. 是否有另一种设置单例不被删除的方法 离开范围后?

【问题讨论】:

  • 你认为对象为什么会被破坏?如果函数始终返回 true,则表示该名称可用(如果 ComponentManager 是新构建的,则不太可能)。此外,您的 createNewEntity 函数实际上并没有创建任何东西。要么您的代码相当奇怪(恕我直言),要么您遗漏了对理解您的问题至关重要的部分。
  • 您是否禁用了复制构造函数?是否可以将返回的单例分配给变量而不是引用?
  • 我将编辑我的问题以获取更多信息。函数 createNewEntity 被简化。当我使用 componentManager 类型的对象时,这个函数在取名时返回 false。

标签: c# c++ dll


【解决方案1】:

C++ static 关键字与 C# static 有点不同。 有关说明,请参阅https://msdn.microsoft.com/en-us/library/y5f6w579.aspx

在第 2 项中它说:2。在函数中声明变量时,static 关键字指定变量在调用该函数之间保持其状态。

尝试不在方法内而是在类范围内声明您的静态(根据上述参考中的第 3 项)。

3.在类声明中声明数据成员时,static 关键字指定该成员的一份副本由该类的所有实例共享。静态数据成员必须在文件范围内定义。声明为 const static 的整数数据成员可以有一个初始化器。

您还需要在文件范围内声明该静态成员。

为什么当它不在 dll 中时它会起作用——目前还不是很清楚。可能是链接器的一种特殊行为。如果在 dll 中声明类,它可能每次都尝试实例化类,并且函数内的静态每次都是新的。但是,如果类在 exe 文件中,那么它每次都是同一个类,并且当您调用方法 _cmpManager() 时,它总是访问该类的同一个实例。

只有我的两分钱 :-)。

【讨论】:

    猜你喜欢
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    相关资源
    最近更新 更多