【发布时间】: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),因此如果您查询相同的上下文,您将获得相同的函数指针。