【问题标题】:loadlibrary fails for current path with GetLastError() == 0当前路径的 loadlibrary 失败,GetLastError() == 0
【发布时间】:2017-09-11 12:54:05
【问题描述】:

我有一个从当前路径加载 DLL 的简单程序

#include <iostream>
#include <windows.h>

using namespace std;

auto loaddll(const char * library) {
    auto dllModule = LoadLibrary(library);
    if(dllModule == NULL)
        throw "Can't load dll";     
    return dllModule;
}

int main() {
    try {   
        auto Handle = loaddll("ISab.dll");
    } catch(const char * error) {
        cerr << "An Unexpected error :" << error << endl;   
        cerr << "Get Last Error : " << GetLastError();
    }
}

加载库对于当前路径中的每个 DLL 都失败,但对于像 User.dll 这样的 DLL 加载库成功

如果我运行它,输出会是这样的

An Unexpected error :Can't load dll
Get Last Error : 0

如果我指定 dll 的完整路径,这也会失败

【问题讨论】:

  • GetLastError() 应该在导致错误的函数之后立即调用。否则它可能会被内部系统调用覆盖,在这种情况下可能是在输出到cerr期间。
  • 不要将问题更改为其他问题,从而使您已经收到的答案无效。我回滚了你的更改。

标签: c++ windows winapi dll


【解决方案1】:

当 Win32 API 调用失败并设置错误代码时,您必须在调用任何其他 Win32 API 函数之前调用 GetLastError。你不这样做。

引发异常、流式传输到cerr 等都可能调用其他 Win32 API 函数并因此重置错误代码。

您的代码必须如下所示:

auto dllModule = LoadLibrary(library);
if (dllModule == NULL)
    auto err = GetLastError();

获得错误代码后,您应该可以更好地了解模块无法加载的原因。 LoadLibrary 的常见错误代码包括:

  • ERROR_MOD_NOT_FOUND 这意味着该模块或其依赖项之一无法通过 DLL 搜索找到。
  • ERROR_BAD_EXE_FORMAT 总是意味着 32/64 位不匹配,无论是与您加载的模块还是它的依赖项之一。

【讨论】:

  • implement a custom exception class - 在大多数情况下std::system_error 就足够了。
  • 不是ERROR_BAD_EXE_FORMAT
  • @zett42:你是否碰巧有一个资源链接,它彻底解释了std::system_error,最好适用于 Windows API 编程?我仍然很难理解,应该如何使用它,以及为什么。
  • 我添加了一些错误检查,你可以看看它
  • 好吧,“不是有效的 Win32 应用程序”,但我在 pascal(inno setup) 中使用 dll 很长时间了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
相关资源
最近更新 更多