为什么在运行时加载OpenGL函数而不是动态链接?

时间:2017-11-23 00:01:54

标签: opengl dynamic-linking dynamic-loading

OpenGL API的用户通常使用诸如GLEW之类的库,或者很高兴在运行时加载OpenGL函数。为什么动态加载首选链接方法?

静态链接显然不是一种选择,因为使用OpenGL的程序通常由作者编译并分发给具有特定图形卡的不同OpenGL库的用户。

留下动态链接和动态加载。似乎动态链接可以工作,因为我们知道我们想要访问的所有函数的名称。

动态链接是否可行?如果没有,为什么?如果是这样,为什么首选动态加载?

2 个答案:

答案 0 :(得分:5)

你想要什么是可能的。您可以使用静态接口创建一个DLL / SO加载器,它将从后台实现加载函数指针。它将根据当前的上下文管理对实现的函数调用。实际上,这实际上是现代Linux发行版的工作方式。

这也是WGL在Windows上运行的方式......无论如何都是OpenGL 1.1版。

它不是“首选”的原因是因为它需要努力。有人必须创建并维护位于应用程序和驱动程序之间的中间库。每当出现新的扩展时,都必须更新库。每当出现新版本时,都必须更新库。然后你必须确保链接到这个库的正确版本。

Linux上有额外的依赖关系,因为它保持最新。然而, Windows 上的OpenGL32.dll却没有。 WinNT已经采用OpenGL一段时间,但微软也已经关闭,创建为Win9x购买了他们自己的图形API。因此,他们从未更新OpenGL32.dll以用于以后的OpenGL版本或新扩展。如果他们愿意不向后兼容,我想他们已经完全从他们的操作系统中抛弃了OpenGL32.dll。

由于您需要一个运行时加载程序才能在Windows中运行,因此使用相同的运行时加载程序使所有平台工作更容易(尽管显然使用不同的函数获取函数指针)。虽然你可以创建你正在谈论的那种DLL,但它只是一个OpenGL加载库,你需要维护一个更多的依赖。如果没有Linux / MESA带来的集中化,那就没有必要了解。

  

我在想,应用程序可以直接动态链接到驱动程序本身而无需中间库

你可以做到这一点。但是,您将使用静态导入库链接到该特定驱动程序库。这意味着如果你链接到NVIDIA的实现,你的应用程序将无法在AMD的实现上运行。

并且您无法静态链接到两个DLL的导入库。原因是如果无法加载一个静态导入库,则应用程序将终止。因此,除非您在计算机上同时使用 AMD和NVIDIA的实现,否则您将无法在任何一台上运行。

此外:

  

因为即使驱动程序库在编译时不可用,我们仍然知道OpenGL函数名称

假设他们的驱动程序直接导出这些名称。这几乎无法保证。

毕竟,WGL / GLX接口是使用wgl/glXGetProcAddress来获取函数指针。如果WGL / GLX和驱动程序之间的接口只是将字符串传递给驱动程序的函数,那么驱动程序不需要直接导出任何函数。它通过单个入口点公开其API,强制运行时函数指针加载而不是允许静态链接。

  

我的理解是OpenGL加载库LoadLibrary / dlopen来自dll / dylib / so库文件,这些库文件本身就是图形卡驱动程序,而那些驱动程序库具有带OpenGL功能的符号表。哪部分是错的?

所有这些都是错误的。您链接到基本接口API(如WGL或GLX)。加载库使用该接口加载函数指针。接口API如何将函数指针加载到驱动程序DLL中是一个特定于平台的问题。在Windows上,wglGetProcAddress调用驱动程序中的函数,传递函数的字符串名称并返回函数指针。

在Linux上,GLX倾向于在内部制造功能,使用后期绑定技术稍后加载实际的驱动程序功能。也就是说,您可以使用一些虚假名称调用glXGetProcAddress,它将返回一个函数指针垫片,当被调用时,它将从驱动程序加载当前上下文的函数。

答案 1 :(得分:1)

OpenGL wiki提供了对OpenGL function loading process的一些了解。并非使用GetProcAddress函数相当于在操作系统本身之外完成的动态链接形式。来自Wikipedia

  

在计算中,动态链接器是操作系统的一部分,它通过复制库的内容来加载和链接可执行文件执行时所需的共享库(在运行时")。从持久存储到RAM,填充跳转表和重定位指针。

OpenGL的扩展程序一直在出现,可以根据供应商和驱动程序平台提供或不提供。 OpenGL wiki在MacOSX上声明:

  自OSX 10.2以来,OSX上的GL功能一直很薄弱;这意味着您可以直接调用它们,未实现的扩展将解析为NULL。请注意,这意味着您必须解析扩展字符串以确定某个函数是否有效,否则您的程序将崩溃。

因此,即使Apple维护了一个动态链接的库,您仍需要添加一个层来检查给定的函数是否可用,具体取决于支持的OpenGL版本和扩展。