C++ 如何从dll使用exe中实现的类

C++ 如何从dll使用exe中实现的类,c++,game-engine,C++,Game Engine,我正在构建一个简单的游戏引擎和一个游戏。我们的想法是在引擎中实现大部分功能和基本类层次结构,这些功能和基本类层次结构应该是exe,然后在引擎提供的工具的情况下,有一个dll来实现特定的游戏。类似于id引擎,例如 然后,引擎将加载dll,获取游戏实例,向游戏指针提供游戏需要的任何函数和数据结构,并调用方法,如game->update()在游戏实例上。到目前为止还不错 我希望在引擎中实现一些基本类,如实体、转换、向量3等。然后在游戏中,我想要的是,例如,从实体派生我的角色 类字符:公共引擎::实体{

我正在构建一个简单的游戏引擎和一个游戏。我们的想法是在引擎中实现大部分功能和基本类层次结构,这些功能和基本类层次结构应该是exe,然后在引擎提供的工具的情况下,有一个dll来实现特定的游戏。类似于id引擎,例如

然后,引擎将加载dll,获取游戏实例,向游戏指针提供游戏需要的任何函数和数据结构,并调用方法,如
game->update()在游戏实例上。到目前为止还不错

我希望在引擎中实现一些基本类,如实体、转换、向量3等。然后在游戏中,我想要的是,例如,从实体派生我的角色

类字符:公共引擎::实体{…}

像这样的东西可以编译,因为我包含了来自引擎的头,但是它们没有链接,因为我不使用obj文件,也不使用来自引擎的cpp文件。我知道为什么这不起作用。据我所知,我的(合理)选择是:

  • 使这些类只作为标题-这样它将始终在任何地方编译 我不想要这个,因为它会增加编译时间、二进制大小等

  • 将公共功能放入lib或dll中
  • 这是可行的,但是一个lib文件意味着我在exe(引擎)和dll(游戏)中编译(链接)了相同的类-这看起来很草率。 Dll可以工作,但是我需要对引擎和游戏进行大量的导出和导入。 可能也是最重要的lib和dll方法都有一个共同的问题,即在开发过程中,由于类层次结构可能会发生很多变化,我可能会在它们之间移动很多类

    我的问题是,还有别的办法吗?对我来说,这似乎是一个非常有用的特性,可以从dll使用exe中的类层次结构。我甚至尝试过一些非常愚蠢的事情,比如让链接器使用引擎编译期间生成的.obj文件,但除非我逐个指定所有的.obj文件,否则它不会起作用(我使用的是Visual Studio 2017)

    我不想放弃这个设计的模块化

    <>强>编辑< /强>:由于DLL是平台特定的,让我们考虑Windows(虽然我想其他平台也会类似)。 这会起作用,但是lib文件意味着我有相同的 在exe和dll中编译(链接)的类

    不,不会的。 这些类将被编译并在共享库中可用(在linux上为.so,在windows上为.dll,在mac上为.dylib),您的可执行文件将从共享库中调用特定方法。它不会在可执行文件中再次编译

    查看<强> > < >强> > C++中的框架或库:

    • 公共部分在标题上显示
      • \uu dllexport(true)
        在类/函数上
    • 私有部分是隐藏的
      • Private甚至不应该存在于公共头上,除非它是d-ptr
      • 这为二进制兼容性增加了更多的安全性
    • 如果使用共享库方法,则不必担心加载时间的增加,这是可以忽略的

    听起来你想利用动态加载,但我认为你可能把事情搞错了。exe通常有游戏代码,.dll有游戏引擎逻辑和类。在.exe代码中加载.dll,并在引擎中注册不同的内容,以便更新和呈现游戏代码

    我现在在想,当我输入这个的时候,是否有一种方法可以翻转它,但这需要在游戏设计逻辑中进行范式转换,游戏只为游戏引擎或其他东西提供更新和渲染功能。这真的是所有你可以依赖的引擎必须是通用的足以处理游戏


    如果我有什么突破性的想法,我会把它贴在这里,但同时这里有一些关于动态加载的信息来帮助你开始

    我对引擎是exe和游戏是dll有点困惑。从另一个角度看,这不是更有意义吗?您引用的部分谈到了lib(静态)方法。动态方法还有我提到的其他缺点。无论如何,谢谢你,我可能会改变一些事情,尽管IdTech的方法看起来很不错。在我看来,有一个引擎控制主游戏循环是有意义的,它只调用game->update()。如果游戏是exe,每个想要制作游戏的人都需要处理主循环。将引擎作为dll更像是一个框架。我可能应该深入研究IdTech4代码,看看它到底是如何实现的。无论如何,谢谢你:)是的,看到成功的项目是如何获得灵感总是很好的。仅供参考有一个游戏开发堆栈交换网站,在那里这些东西可能更合适。这里有一个关于从关卡编辑器中分离引擎和游戏的问题,您可能会觉得有趣。在引擎的概念上,您是对的,引擎必须具有足够的通用性,以调用游戏内容的更新,但您希望程序员至少能够使用您的引擎代码来注册对象。要做到这一点,您需要让他们“加载”要使用的代码。这就是它通常放在.dll中的原因。除非您正在设置共享内存,否则无法从.exe加载。最后,我们将讨论其他具有实际游戏逻辑的代码如何编译和加载引擎代码。然而,只要一个独立的程序员可以用引擎(在正常的设置中,引擎在.dll中)或c注册游戏对象,您就无法实现这一点
    Put the common functionality into a lib or a dll.