c++ - 避免包装器 DLL 中的堆栈溢出

标签 c++ visual-studio dll wrapper dynamic-linking

我有一个要添加全屏后处理效果的程序。我没有该程序的源代码(它是专有的,尽管开发人员确实向我发送了调试符号的拷贝,.map 格式)。我已经编写并运行了效果代码,没问题。

我现在的问题是将两者联系起来。

到目前为止,我尝试了两种方法:

使用Detours修改原程序的导入表。这很好用并且保证稳定,但我与之交谈过的用户对此并不满意,它需要安装(除了提取存档之外),并且根据条款使用 Detours 修补程序是否有效存在一些问题最终用户许可协议(protocol)。因此,该选项已被淘汰。

另一种选择是传统的 DLL 替换。我已经包装了 OpenGL (opengl32.dll),我需要程序来加载我的 DLL 而不是系统拷贝(只需将它放入具有正确名称的程序文件夹中,这很容易)。

然后我需要我的 DLL 来加载 Cg 框架和运行时(它依赖于 OpenGL)和其他一些东西。当 Cg 加载时,它会调用我的一些函数,这些函数会调用 Cg 函数,而我往往会出现堆栈溢出和无限循环。我需要能够将 Cg DLL 包含在子目录中并仍然使用它们的函数(不确定是否可以让我的 DLL 导入表指向子目录中的 DLL)或者我需要动态链接它们(我' d 宁愿不做,只是为了简化构建过程),迫使他们引用系统文件(不是我的自定义替换)。

整个链是:程序加载 DLL A(名为 opengl32.dll)。 DLL A 加载 Cg.dll 并动态链接 (GetProcAddress) 到 sysdir/opengl32.dll。我现在需要 Cg.dll 也引用 sysdir/opengl32.dll,不是 DLL A。

这将如何完成? 编辑:如何在不使用 GetProcAddress 的情况下轻松完成此操作?如果没有别的办法,我愿意回到那个,但如果可能的话,我宁愿不这样做。

Edit2:我刚刚在 MSDN 文档中偶然发现了函数 SetDllDirectory(在完全不相关的搜索中)。乍一看,这看起来像我需要的。是这样吗,还是我判断有误? (现在开始测试)

Edit3: 我已经通过稍微不同的方式解决了这个问题。我没有删除 OpenGL32.dll,而是将我的 DLL 重命名为 DInput.dll。它不仅具有不必导出一个函数而不是超过 120 个(对于程序、Cg 和 GLEW)的优点,而且我不必担心函数运行回来(我可以像往常一样链接到 OpenGL) .为了进入我需要拦截的电话,我使用了 Detours。总而言之,它的效果要好得多。不过,这个问题仍然是一个有趣的问题(希望对将来尝试做疯狂事情的​​其他人有用)。两个答案都很好,所以我还不确定该选哪个...

最佳答案

SetDllDirectory 可能不会 工作。 Cg.dll 可能只是链接到 OpenGL.dll。当操作系统加载 Cg.dll 时,它发现已经有一个模块加载了那个名称(你的),所以它将 Cg 与那个链接,而不是去寻找其他拷贝。也就是说,SetDllDirectory 修改的搜索顺序甚至从未发挥作用,因为操作系统不进行任何搜索。

我怀疑您最好的选择确实是检测对您的库的重新进入调用。当您检测到一个时,而不是进行自定义处理,而是将调用直接转发到真正的 OpenGL 库,由于调用了 LoadLibrary,然后为库的每个函数调用了 GetProcAddress,因此您可以引用该库。

关于c++ - 避免包装器 DLL 中的堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2760716/

相关文章:

asp.net - Visual Studio 不要打开新的浏览器实例

c++ - 无法编译此 SDL 类(class)... :/

c# - 将完成的项目转换为 DLL

c - 如何优雅地将大量方法指针传递给用 C 编写的 DLL?

linux - C/C++格式字符串中的填充如何存储在Linux的虚拟内存中?

c++ - 将 << 运算符重载为 "friend"函数以打印 BST - C++

c++ - "static enum"在 C++ 中是什么意思?

c++ - UVA 3n+1 (prob 100) 错误答案但所有测试用例都通过了

c++ - 2个默认复制构造函数: is it possible?

c++ - Visual Studio C++ : When should I be using __declspec(dllimport)?