【发布时间】:2019-05-24 04:57:59
【问题描述】:
不知道如何命名标题,所以可以随意重命名,但我遇到的问题是我有一个功能可以在一个项目中工作,但在另一个项目中失败。下面是粗略的伪代码,显示 LibraryProject 中的一个调用有效,而 GameProject 中的调用无效。
在ChildClass::do_stuff 中,win32_window HWND 是有效的,而第二个,failed_win32_window 是 null 并且 glfw 抛出一个错误,说它没有被初始化,尽管它已经被初始化(因为第一次 glfw 调用成功我已经手动验证它是):
GLFWError #65537 Happen, The GLFW library is not initialized
这是显示两个项目和文件的伪代码。 GLFW 已正确设置初始化,因为如果我在 LibraryProject 中执行所有 glfw 逻辑,则窗口会正常显示。
//LibraryProject
////library_header.h
class ParentClass {
GLFW* _mainWindow; //filled in elsewhere in the real code
HWND getWin32Window() { return glfwGetWin32Window(_mainWindow); }
}
//GameProject
////game_header.h
#include "library_header.h" //from other Project
class ChildClass : public ParentClass {
void do_stuff() {
HWND win32_window = this->getWin32Window(); //this works because it goes down into LibraryProject.dll's module
HWND failed_win32_window = glfwGetWin32Window(_mainWindow); //but literally the same call here doesn't because it happens within GameProject.exe
}
}
////game_body.cpp
void function_called_elsewhere_in_game() {
//called from GameProject.exe
auto child = ChildClass();
child.do_stuff();
}
我不确定这是否是 glfw 和我的设置的问题,或者只是我对项目和依赖项如何工作的误解。
我尝试过的事情:
- 下载最新glfw3
- 重建整个解决方案
- 切换引用和链接依赖输入
注意事项:
- 这发生在主线程中,没有其他东西同时使用 glfw。它也可以 100% 重现。
-
glfw3.lib总是在我的 GameProject 输出文件夹中创建,基于 LibraryProject 中的文件夹 - 对两个
glfwGetWin32Window调用中的每一个进行反汇编时,反汇编中的地址都不同,这让我相信它们是同一个库的两个不同副本,但我不确定。 - 这不是 cocos2d 的问题,我用作启动空白项目并调用
glfwGetWin32Window(..)的游戏引擎返回一个有效指针,即使在 GameProject 中也是如此,所以有些事情我做错了,但我没有不知道是什么。
展示实际行为的图片。 magnolia_cocos_proj 是 GameProject 并且是我正在运行的 exe,libcocos2d 是我用作 DLL 的 LibraryProject(我不熟悉链接和 dll 的工作原理)。
【问题讨论】:
-
您的应用程序是多线程的吗?来自 glfw 文档:大多数 GLFW 函数只能从主线程(调用 main 的线程)调用
-
除了主线程之外,这些调用都不会发生在任何地方,我会确保编辑问题,谢谢!
-
诊断非常明确,它表示您的程序尚未调用
glfwInit()。在 sn-p 中看不到这样的调用,所以这是可能的。造成这种情况的一个可能原因可能是对一个看起来不像程序入口点的函数使用了名称“main”。如果链接器选择了那个来启动您的程序,那就太糟糕了。选择另一个名字。另一个可能的原因是库不止一次地链接到程序中。如果 LibraryProject 是一个 DLL 项目,则可能会发生这种情况,但它看起来不像一个。 -
@HansPassant
glfwInit()在 LibraryProject 中被调用,我自己可以通过步进验证这一点。 LibraryProject 是一个 dll 项目,然后双链接听起来像是一种可能性。我已经更新了问题以澄清其中一些要点 -
@TankorSmash 请检查您的 Child 构造函数,它不包含
_mainWindow的副本。如果这样做,您可能可以通过 Parent 访问有效版本,但这并不意味着它在 Child 中已正确初始化。有关示例,请参见 godbolt.org/z/GMxiTC。
标签: c++ visual-studio-2013 linker glfw