【问题标题】:Safety of using DLLs as C++ game SDK release (dll modified, exe never)使用 DLL 作为 C++ 游戏 SDK 版本的安全性(dll 已修改,exe 从不)
【发布时间】:2013-06-24 15:48:26
【问题描述】:

我一直在尝试想出最好的方法来分发我的游戏代码的一部分,但不是全部,以便让人们可以修改游戏,但不能使用我的代码创建独立游戏。这就是已经有多少游戏可以运行,例如 Doom3 - 在 GPL 发布之前,SDK 只是为不可修改的 EXE 创建 DLL 的代码的一部分。

为此,我成功地将我的代码拆分为 EXE/SDK,但我担心的是 EXE 引用了 SDK 中的类。例如,如果我编译具有 Entity 类型对象数组的 EXE,则在 SDK 中声明 Entity,然后向该类添加另一个成员变量,编译 DLL,然后运行旧的 EXE新的DLL,是不是说明EXE有不正确的Entity大小信息?

还是我想多了?

【问题讨论】:

  • 使用 dll 和 exe 的版本控制以确保它们兼容。如果您对 dll 中的类进行此类更改,那么您将增加其版本号。然后可执行文件将检查 dll 版本号,如果它不兼容,应该会正常失败。
  • 这行不通,因为首先拥有 DLL 的目的是允许其他人在没有完整源代码的情况下进行修改。
  • 他们对 dll 做了什么修改,还是说 dll 附带的头文件?
  • SDK 中包含他们想要的任何东西。 Doom3 在这方面非常灵活,SDK 中有大量代码可以随心所欲地更改,但 EXE 仍然有一大堆重要的东西,有时看起来几乎是随机的什么东西不包括在内。

标签: c++ dll sdk shared-libraries


【解决方案1】:

“如果你修改这个类,它将无法与其他地方定义的类一起工作。

这些问题也有很多解决方案。

通常使用(智能)指针和/或引用而不是类本身来形成接口,以避免代码的两个部分必须就类的大小达成一致。

因此,例如,而不是:

class EntityCollection
{
  private:
   vector <Entity> entities;
  public:
   void addEntity(Entity e) { entities.push_back(e); }
   void removeEntity(Entity e) { ... } 

};

我们将使用指针式存储(应该真正使用智能指针,但为了简短起见,我不是):

class EntityCollection
{
  private:
   vector <Entity*> entities;
  public:
   void addEntity(Entity* e) { entities.push_back(e); }
   void removeEntity(Entity* e) { ... } 

};

现在,无论实体有多大,或者它包含什么,它在向量中仍然是“指针大小”。

另一个变体是有一个“pimpl”接口。你有一个主类定义,里面是一个(智能)指向实现类的指针,它提供了一组已知的虚函数。

类似这样的:

class Entity
{
   public:
     class EntityImpl 
     {
        virtual int func()  = 0;
        ...
     };
     Entity(EntityImpl* impl) pImpl(impl) {}
     ...
     int func() { return pImpl->func(); }
   private:
     EntityImpl* pImpl;
};

这些当然不是您唯一可能关心的问题,但应该会给您一些“这是您用来解决问题的东西”的想法。

【讨论】:

  • 谢谢,我知道这个例子有一个简单的答案,但我不能完全理解它。我仍然担心通过这种“允许用户编辑DLL而不是EXE”的情况可能会出现什么样的不可预见的问题。
  • 除了“表现不佳的 DLL 会使可执行文件崩溃”之外,这并不是一个未知的场景。许多商业程序的插件是 .dll(或 Linux 中的 .so 文件)。由于崩溃只会真正破坏该用户的体验,因此并没有那么糟糕。
猜你喜欢
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多