重命名 DLL 会导致使用它的代码崩溃
我有一个用本机 C++ 编写的 DLL。 Visual Studio 项目名称为 MyDll
,它会编译为输出目录中名为 MyDll.dll
的文件。
编译后,我将其重命名为MyDll2.dll
。 (这个示例看起来很愚蠢,但我有充分的理由重命名它。)
用 C++/CLI 编写的第二个项目使用此 DLL。
在编译时,该项目引用 MyDll.lib
(编译 MyDll 时生成)以便能够使用 dll 中定义的类。
在运行时,为了加载 DLL,我调用 LoadLibrary,向其传递文件 C:\...\MyDll2.dll
的完整路径(它实际上位于同一文件夹中)。加载成功,如LoadLibrary的返回值所示。
在代码中第一次出现我使用 DLL 中定义的类(仅在堆栈上声明一个对象)时,它会因 SEHException
崩溃(这些异常不提供有关崩溃原因的任何信息) ...)
只有当我执行重命名步骤时才会发生这种情况。如果我将其保留为 MyDll.dll 并对该文件调用 LoadLibrary,则一切正常。所以这显然是由于更名造成的。
有什么想法吗?我不允许重命名 DLL 吗?
(编辑:通过提供更多详细信息进行澄清)
I have a DLL which is written in native C++. The Visual Studio project name is MyDll
and it compiles to a file called MyDll.dll
in the output directory.
After compilation, I rename it to MyDll2.dll
. (This example seems silly but I have a good reason for renaming it.)
A second project, written in C++/CLI, uses this DLL.
At compile time, this project references MyDll.lib
(generated when MyDll is compiled) to be able to use classes defined in the dll.
At runtime, to load the DLL, I call LoadLibrary, passing it the full path of the file C:\...\MyDll2.dll
(it's actually in the same folder). It loads successfully, as shown by LoadLibrary's return value.
At the first occurence in code where I use a class defined in the DLL (just declaring an object on the stack), it crashes with an SEHException
(these exceptions give no information whatsoever about the cause of the crash...)
This only happens if I do the renaming step. If I leave it as MyDll.dll
and call LoadLibrary on that file, everything works fine. So it is obviously due to the renaming.
Any ideas why? Am I not allowed to rename the DLL?
(EDIT: clarifying by giving more details)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
构建 dll 时,链接器还会生成一个 lib 文件,您可以使用该文件在可执行文件中链接。此 lib 文件包含从中导入导出函数和数据的 dll 名称。因此,您的可执行文件中引用了原始名称 dll。
When building a dll the linker also generates a lib-file which you use to link with in your executable. This lib file contains the dll-name from which the exported functions and data are being imported. So your executable has references to originally name dll in it.
为什么加载 DLL 后要重命名它?调用 LoadLibrary 后切勿重命名 DLL。我很惊讶操作系统竟然允许你这样做。
Why are you renaming a DLL after it's been loaded? You should never rename a DLL after you called LoadLibrary. I'm surprised the OS would even allow you to do that.
。是的,当您重命名 DLL 时,必须更改 LoadLibrary() 参数。解决您真正的问题,听起来您根本没有检查 LoadLibrary() 的返回值。返回 NULL 时抛出 Win32Exception。
Yes you do, the LoadLibrary() argument must be changed when you rename the DLL. Fix your real problem, it doesn't sound like you check the return value of LoadLibrary() at all. Throw a Win32Exception when it returns NULL.
我同意埃德温的观点。 lib 文件指向导出的函数,并且还包含编译时的 dll 名称。
I agree with Edwin. The lib file directions to exported functions and also contains the name of dll which was at compile time.
我不知道一年后是否有人会读到这篇文章,但为什么 OP 甚至在这个重命名的 dll 已经静态链接的情况下 LoadLibrary 呢?这是两件不同的事情。我认为OP的应用程序崩溃是由于缺少静态链接后所需的MyLib.dll,而LoadLibrary与此无关,OP也可以省略MyLib2.dll的LoadLibrary,结果将完全相同。我唯一无法解释的是提到的未知错误。
I don't know if anyone will be reading this after a year, but why was OP even LoadLibrary'ing this renamed dll when it was already statically linked? This is 2 different things. I think OP's app was crashing due to lack of MyLib.dll, required after static linkage, and LoadLibrary has nothing to do with it, OP could as well omit LoadLibrary of MyLib2.dll and the result would be exactly the same. Only thing i can't explain is unknown error mentioned.