【问题标题】:How to use Glad in DLL and exe如何在 DLL 和 exe 中使用 Glad
【发布时间】:2020-12-16 21:14:55
【问题描述】:

有没有办法在 DLL 和 exe 中使用 Glad?我觉得可能存在问题,因为 DLL 有自己的与 exe 分开的内存空间,但我不确定如何重构我的代码来表示这一点。

我的情况是我有一个游戏引擎,其中包含许多使用由glad 加载的OpenGL 函数的方法,例如着色器、纹理和其他与渲染相关的内容。但是,我将引擎导出为 dll(出于各种其他原因),并且运行时编辑器链接到该 dll。这个运行时编辑器也需要访问glad函数,因为它静态链接到imgui,它需要相同的窗口上下文和所有内容,我假设如果我在dll和exe中调用gladLoadGL()我会得到不同的功能指针,这意味着它们不会对相同的数据进行操作。有没有办法做到这一点?我也尝试将 GLFW 链接为 DLL,但这无济于事(这是有道理的,因为这是一个令人高兴的问题)。如果我在我的 exe 中不执行gladLoadGL(),则在尝试执行 gl 函数时会出现 nullptr 异常(因为只有少数情况下我在运行时编辑器中使用 glFunctions)。但是,如果我确实在我的 exe 中运行了gladLoadGL(),它会加载新的函数指针,这会抛出所有问题,并且我会在 ImGui 中出现错误,我假设这是因为glad 在 DLL 和 exe 中加载了不同的函数指针。

这可以做到吗,还是我需要重新考虑我的整体架构?

编辑:所以我最初的问题得到了回答,你不必做任何特别的事情(除了在 DLL 和 exe 中加载高兴的函数)。然而,这在我的代码中引发了一个新问题,这似乎是实际问题所在。现在我在 DLL 中有一个类,看起来像这样:

// In the DLL
class __declspec(dllexport) Application 
{
  Application();

  void Construct(); // I added this because the base constructor would not be called

  virtual void SomeFunc() {} // These are overridden by whoever inherits this class
  virtual void SomeOtherFunc() {}
}

// In the exe
class MyApp : public Application
{
  MyApp() 
  { 
    Construct() // This raises a runtime exception that says the method could not be found. 
    //Is there any way to make sure I export and import this correctly as well?
  }
}

编辑 2:原来我只是错过了构建步骤,并且从未将我的 dll 复制到 exe 所在的位置。再次感谢所有的帮助

【问题讨论】:

  • "我会得到不同的函数指针,这意味着它们不会对相同的数据进行操作"你认为为什么会这样?
  • @NicolBolas 因为 dll 有自己的虚拟内存。因此,当 dll 调用 glLoad 时,它将函数指针加载到其内存空间中,然后当我在 exe 中调用 glLoad 时,它将新函数指针加载到其内存空间中。如果我对如何在操作系统上执行 dll 的理解是正确的,如果我错了,请随时纠正我。
  • 嗯,你的理解不正确。正确的是,如果您不从您的 DLL 中导出高兴的函数指针,则其余部分需要单独设置,但这与内存空间无关(整个 进程 将使用它自己的地址空间,而不是它加载的每个库),但在动态链接期间具有符号可见性。 GL 函数指针是每个 GL 上下文(甚至实际上是 Windows 中的每个 ICD),因此如果您查询相同的上下文,您将获得相同的函数指针。

标签: c++ opengl dll glfw glad


【解决方案1】:

记住指针变量和它所指向的变量之间的区别很重要。如果在 DLL 中有一个 GLAD 实例,在 EXE 中有另一个,那么对于每个 GLAD 函数指针,您将有两个指针变量。

但是,它们都将指向相同的函数。它们毕竟是为同一个 OpenGL 上下文加载函数指针。所以这些指针将指向相同的函数。

因此,虽然从技术上讲,您会浪费一些存储空间(因为 DLL 和 EXE 都需要指针变量),但只要加载指针时 OpenGL 上下文是当前的,它应该仍然可以正常工作。

【讨论】:

  • 谢谢@NicolBolas。这对我来说缩小了范围,事实证明我没有在 DLL 中创建上下文。然而,这确实给我提出了另一个问题。现在我在 exe 中有一个从 dll 中的超类继承的子类,当我尝试导出该类时,它说它找不到超类的方法。我将使用代码 sn-p 编辑上面的问题,我知道现在这是一个不同的问题,但如果您有任何见解,它仍然会很棒。我将其标记为正确,因为它回答了原始问题:)
猜你喜欢
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多