8

我有一个程序做一些图形。当我以交互方式运行它时,我希望它使用系统中的 OpenGL 来提供硬件加速图形。当我批量运行它时,我希望能够重定向它以使用 Mesa GL 库,以便我可以使用 OSMesa 功能呈现到屏幕外缓冲区。如果选择了批处理启动选项,则通过执行 LoadLibrary/GetProcAddress 启用 OSMesa 功能。

在 Linux 上,完成这项工作相当容易。通过使用包装脚本来调用程序,我可以执行以下操作:

if [ "$OPTION" = "batch" ]; then
  export LD_LIBRARY_PATH=$PATHTO/mesalibs:$LD_LIBRARY_PATH
fi

可以在 Windows 中执行此操作吗?

当我尝试将目录添加到 PATH 变量时,程序继续转到系统 opengl32.dll。让程序使用 Mesa GL/OSMesa 共享库的唯一方法是让它们与我的程序位于同一目录中。但是,当我这样做时,程序将永远不会使用系统 opengl32.dll。

4

4 回答 4

8

如果我正确理解了您所说的内容,那么当您的进程启动时正在加载错误版本的 opengl32.dll,即加载时动态链接。在不改变这一点的情况下,可能没有解决问题的好方法。

你说你不能方便地使用opengl32.dll 的运行时动态链接(LoadLibrary/GetProcAddress),因为对它的调用来自 Qt 库。但是,我认为 Qt 库本身是动态链接的,因此您应该能够通过对其使用运行时链接来解决您的问题。在这种情况下,如果您在加载 Qt 库之前加载 opengl32.dll,您应该能够明确选择要加载的 opengl32.dll 版本。

您可能需要考虑使用延迟加载来简化从加载时链接到运行时链接的过程。在这种情况下,第一次调用 Qt 库会导致它自动加载,您只需要先显式加载 opengl32.dll。

于 2012-02-01T04:04:08.843 回答
1

有几种方法可以处理这个问题,具体取决于库及其名称/位置:

如果两者具有相同的名称(opengl32.dll),那么您需要将 Mesa DLL 位置添加到搜索路径,以便在系统目录之前搜索它。签入的订单目录在此处详细说明。如您所见,$PATH最后出现在系统之后,因此您不能只将目录添加到其中。但是,您可以通过将工作目录设置为包含台面文件的路径来利用第二步(“当前目录”)。通常这意味着在包含文件的目录中使用绝对路径启动应用程序。

不过,这仍然不是特别令人愉快。如果可以,您应该在应用启动时使用LoadLibrary并检查环境变量 ( )。OPENGL_LIBRARY_PATH假设来自 Mesa 的 DLL 的导出opengl32.dll是相同的,您可以执行以下操作:

void LoadExports()
{
    char location[MAX_PATH];
    getenv("OPENGL_LIBRARY_PATH", location);
    HMODULE oglLib = LoadLibrary(location);

    function1 = GetProcAddress(oglLib, "glVertex2f");
    ...
}

这将完全正常,几乎完全按照您的意愿行事。

但是,如果您想这样做,则不能 import opengl32.dll,您可能正在这样做,您必须在整个过程中动态链接。确保不要链接反对opengl32.lib,你应该没问题。根据您使用的函数数量,设置起来可能会很痛苦,但是代码可以很容易地编写脚本并且只需要完成一次,您还可以使用static变量在程序的整个生命周期内缓存结果。也可以为不同的库使用不同的函数名称,尽管这需要更多的逻辑,所以我将把细节留给你。

于 2012-01-30T13:58:39.153 回答
0

虽然这在 cmd 窗口中应该是可能的,但您似乎没有运气。

尝试:在您的脚本中设置一个变量(RUNNING_IN_SCRIPT=Y),然后在您的可执行文件和 LoadLibrary 中从安装的绝对路径解析该变量 - 请务必在退出时清除该变量。

于 2012-01-25T19:08:47.423 回答
0

Windows 以前搜索动态库的路径不同,但出于安全考虑,先搜索系统路径。

但是,您可以使用延迟加载导入来获得解决方法:

如果您使用的是 MSVC,则可以将您有兴趣自行加载的 DLL 与/DELAYIMPORT链接器的标志分开。

然后,覆盖延迟加载辅助函数并使用它LoadLibrary来找到正确的 DLL(而不是信任系统)。

加载正确的 DLL 后,让您的帮助函数只调用将GetProcAddress自行完成所有业务的原始函数。

于 2012-02-01T12:59:43.770 回答