【问题标题】:LoadLibrary: Error 126 when compiling with Visual C++, but works fine with NetBeans/MingGW?LoadLibrary:使用 Visual C++ 编译时出现错误 126,但使用 NetBeans/MingW 可以正常工作?
【发布时间】:2014-05-02 11:39:10
【问题描述】:

我遇到以下问题:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


int main() {

HANDLE handle;
DWORD dw;

handle = LoadLibrary("C:\\Folder\\mydll.dll");

dw = GetLastError();

printf("Loading Library: %d", dw);

FreeLibrary(handle);

return 0;
}

使用 Netbeans/MinGW 编译时,一切正常,DLL 已加载,输出为“Loading Library: 0”。

但是,当使用 Visual C++ 2008 Express 在完全相同的机器上编译完全相同的代码时,我得到了臭名昭著的 126 错误:“Loading Library: 126”。

DLL 显然存在于指定位置并且加载它也可以正常工作 - 当我将 Netbeans 与 MinGW 一起使用时。但是为什么用Visual C++就不行呢?

这只是概述我的问题的示例代码。它是一个更大的项目的一部分,在使用 Netbeans/MinGW 编译时可以正常工作,但在使用 Visual C++ 编译时不会加载 DLL...

感谢所有回答!

【问题讨论】:

  • mydll.dll 可能依赖于使用 VC++ 加载时发现的其他 dll。尝试像 dependency walker 这样的工具,并确认所有依赖的 dll 都存在于 %PATH%
  • 我已经尝试过了,Dependency Walker 确实向我展示了缺少几个 DLL:API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.DLL API-MS-WIN-CORE- WINRT-ERROR-L1-1-0.DLL API-MS-WIN-CORE-WINRT-L1-1-0.DLL API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL API-MS -WIN-CORE-WINRT-STRING-L1-1-0.DLL API-MS-WIN-SHCORE-SCALING-L1-1-1.DLL DCOMP.DLL IESHIMS.DLL 但是为什么它与 Netbeans 一起工作呢?此外,我发现有人说 Dependency Walker 具有误导性的帖子:stackoverflow.com/questions/17023419/win-7-64-bit-dll-problems
  • 那些可能在 Netbeans 等中可用。顺便说一句,你的 dll 名称是 "...\mydll.dll",而它应该是 "...\\mydll.dll",你缺少 '\'。跨度>
  • 好的...刚刚检查了两个 .exe,VSC++ 文件为 30 kb,而 Netbeans 文件为 41 kb...所以我猜有一些链接正在进行。至于路径名,那是一个错字。我在这里发布 sn-p 时更改了它。在原始文件中,它是 \\mydll.dll。
  • 请注意,操作系统不会在 DLL 所在的文件夹中搜索依赖的 DLL,而是在 EXE 所在的文件夹中(以及其他)。 This document 非常详细地描述了搜索过程,但无论如何,C:\Folder 一般不会被搜索到。我的猜测是,一个 EXE 可以工作,而另一个不仅仅是因为您以不同的方式运行它们 - 从不同的目录和/或使用不同的当前工作目录。星星恰好在一种情况下对齐,而在另一种情况下却没有对齐。

标签: c visual-c++ netbeans dll loadlibrary


【解决方案1】:

因为你的回答不完整,漏掉了真正的问题,我在这里详细说明一下。

您正在编译定义了UNICODE 的MSVS 版本,这使得LoadLibrary 之类的东西被定义为LoadLibraryW 的宏,它接受const wchar_t* 参数。相反,当使用 GCC 编译时,您无需定义它,它可以工作。

UNICODE 版本实际编译的原因在某种程度上是 MSVS 中的一个错误/功能,它允许您将 char* 传递给 wchar_t* 而没有任何消息(您确实打开了警告,不是吗?) .这会导致某些被误解的字符串传递给 Win32 API 函数,从而无法找到乱码文件名。

这就是为什么我总是直接调用*W 版本的函数,并且不理会所有有趣的UNICODE 的东西。

【讨论】:

  • 是的,谢谢。我将项目的属性更改为“多字节字符集”,现在甚至原始代码也可以在 Visual C++ 中使用。这样做有什么问题吗?因为错误不是发生在我的代码中,而是发生在我必须用于我的项目的第三方库中。这是我第一次使用 Microsoft IDE……所以真正发生的事情是,由于宏,我在 MSVS 中的 LoadLibrary 调用实际上调用了另一个函数,而不是使用 GCC 的 LoadLibrary 调用?
  • LoadLibrary(以及 Win32 API 中的许多其他函数以类似的方式)映射到 LoadLibraryALoadLibraryW 如果 UNICODE 未定义或已定义。为什么不匹配的调用不会导致编译错误,我不知道,但我强烈建议我们的代码独立于构建系统(即您的项目在 VS IDE 中的属性)决定做什么。或者至少在任何地方都保持一致,这在便携性上是非常困难的。
  • @clancy688 我遇到了同样的问题,将项目设置为使用“多字节字符集”构建也解决了我的问题。谢谢!
【解决方案2】:

我现在已经找到了解决方案。 FreeLibrary("mystringpath.dll") 显然不起作用。但是当我用 LPCWSTR 调用该函数时,它可以工作。所以:

handle = LoadLibrary("C:\\Folder\\mydll.dll");

使用 Visual C++ 编译时产生 ERROR_MOD_NOT_FOUND,但使用 MinGW 编译时有效。

但使用 Visual C++ 编译时,以下内容有效:

LPCWSTR path = L"C:\\Folder\\mydll.dll";

handle = LoadLibrary(path);

并返回 ERROR_SUCCESS (0)。

因此,dependency walker 指出的所有据称丢失的 dll 都不是问题所在。

不过,有趣的是,在 Netbeans/MinGW 中使用修复会导致 Netbeans .exe 返回 126。编译时,gcc 抱怨从不兼容的指针类型传递参数。

所以第一个代码只适用于 MinGW,第二个只适用于 Visual C++...

经过进一步研究,我意识到这个修复是不必要的。显然,问题在于我的 Visual C++ 项目默认使用 Unicode 字符集。在项目属性中将其更改为多字节字符集后,粘贴在原始问题中的代码在 Visual C++ 中也可以正常工作...

【讨论】:

    猜你喜欢
    • 2021-04-20
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多