将 opengl Window 转换为 std::size_t 并再次在 Linux 中有效,但在 OS X 中无效

Posted

技术标签:

【中文标题】将 opengl Window 转换为 std::size_t 并再次在 Linux 中有效,但在 OS X 中无效【英文标题】:convert opengl Window to std::size_t and back again works in Linux, but not OS X 【发布时间】:2011-06-01 22:40:48 【问题描述】:

我已成功将 OpenGL 窗口转换为 std::size_t 变量,然后将其转换回 Linux 中的 OpenGL 窗口。但是,当我尝试在 Mac OS X 中做同样的事情时,它不起作用。这就是我正在做的事情:

/* our window instance(This is an X Window System Window!) */
    Window window_;
.
.


.
.
std::size_t OSXGLWindow::getWindowHandle() 
    return window_;

.
.

调用“getWindowHandle()”只是将 Window 作为 std::size_t 返回。

我将这个 size_t 窗口句柄传递给以下函数:

IInputManager* InputFactory::getInputMgr(std::size_t winHandle) 

    IInputManager* retObj = 0;
#ifdef _WIN32
    // todo: windows input implementation
#endif

#ifdef linux
    Window win = winHandle;
    retObj = new lwis::linuxos::LinuxInputManager(win);
#endif

#ifdef __APPLE__
    Window win = winHandle;
    retObj = new lwis::osx::OSXInputManager(win);
#endif

    return retObj;

LinuxInputManager 和 OSXInputManager 都调用以下代码:

XSelectInput(display_, theWindow,
            KeyPressMask | KeyReleaseMask | KeymapStateMask) == BadWindow)

其中“theWindow”是从“InputFactory::getInputMgr(..)”函数发送到相应对象的构造函数的窗口。

“XSelectInput”在 Linux 的 LinuxInputManager 对象中成功,但在 OS X 的 OSXInputManager 中失败。

另一个重要的信息是 Window 在 2 个静态库之间传递,这就是为什么它首先被转换为 std::size_t (以便于在库之间传递)。

有人知道这是为什么吗?有没有更好的方法在库之间传递句柄? 'void*' 会是更好的选择吗?

【问题讨论】:

究竟什么是“OpenGL 窗口”? 每个环境中 std::size_t 的底层类型是什么? @genpfault 抱歉,我忽略了“Window”是一个 X Window 系统窗口。 @geofftnz 我的印象是 std::size_t 始终是无符号整数类型。 有没有可能是一个64位,另一个32位?或者可能两者都是 32 位的,但您试图通过它推送的是 64 位? 【参考方案1】:

那么,您为什么期望其他一些不相关的类型 Window 可以转换为 std::size_t 并返回而没有任何损失?我猜你不会对unsigned char 不能担任那个角色感到惊讶,对吗?如果是这样,为什么看到size_t 失败,您会感到惊讶?

size_t 只是一些无符号整数类型,具有一定的大小和范围。如果您将一些不相关的类型转换为size_t,则转换结果可能适合size_t,或者可能不适合它,具体取决于平台、源类型的属性等。显然,这正是发生的情况在你的情况下。

【讨论】:

嗯..我对 C++ 还是比较陌生,但我想要完成的是隐藏传递给 getInputMgr(..) 方法的 种类 窗口.我可能想发送 X Window 以外的东西。我使用 std::size_t 的原因是我注意到另一个库以这种方式使用它,我想“我想这就是它的完成方式”.. 下面的@totowtwo 表明 void* 是完全可以接受的,它实现了目标,我只是不确定这是否是“正确”的方法(正如我所提到的,我正在跟随另一个图书馆的 std::size_t 领导)。谢谢! 鉴于 X11 中的 Window 类型是不透明的,并且您对此一无所知,因此无法可移植地将其转换为任何内容。适用于一种架构的东西可能不适用于另一种架构。话虽如此,Window 在我见过的每个 X11 实现中都被定义为 32 位无符号整数。 (这确实让size_t 无法在 Mac OS X 上运行有点神秘。) 我发现我的 Mac 是 64 位架构,我想这可以解释它..std::size_t 是 8 字节,而窗口只有 4 字节..可能在转换时会导致问题。关于Window,这是一个很好的观点。我认为void* 会给我最好的便携性(我现在才开始我的 Windows (XP) 端口,所以我想时间会证明这一点):) 再次感谢安德鲁 @Jarrett:如果确实需要使用整数类型来临时存储指针值,正确的类型是uintptr_t,而不是size_tuintptr_t 在 C++ 中没有正式可用(它是 C99 类型定义),但许多平台都提供了它,您可以随时自行定义。【参考方案2】: 如果您不能向 getInputMgr 提供 GL 类型信息,

void* 将是一个不错的选择。我假设您正在尝试从其余代码中隐藏 OpenGL 定义?

【讨论】:

抱歉,我忽略了“Window”实际上是一个 X Window 系统窗口。我已经相应地编辑了我的帖子。我试图完成的是隐藏传递给 getInputMgr(..) 方法的那种窗口。我可能想发送 X Window 以外的东西。

以上是关于将 opengl Window 转换为 std::size_t 并再次在 Linux 中有效,但在 OS X 中无效的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL:将 VBO 与 std::vector 一起使用

将 std::string 转换为 std::wstring 时,C++17 codecvt 抛出“错误转换”

将 Glut 鼠标坐标转换为 opengl

如何将 OpenGL 纹理转换为 CUDA 纹理?

将 OpenGL 绘制列表转换为顶点数组或 VBO

如何将 2D 世界转换为屏幕坐标 OpenGL