【问题标题】:c# - using LoadLibrary returns 0 with Win32Error 193c# - 使用 LoadLibrary 返回 0 和 Win32Error 193
【发布时间】:2017-09-09 12:55:21
【问题描述】:

我正在构建一个 C# 类库,它调用我们正在合作的供应商提供的第三方 DLL。供应商示例都在 vc++ 中,并且正在运行和工作。

我正在尝试加载其中一个 DLL,它返回一个 IntPtr 0。当我调用 Marshal.GetLastWin32Error() 时,我得到 193,从我读到的意思是我正在尝试加载 32 位64 位应用程序中的 DLL。但我一次又一次地检查,我的类库都设置为x86,调用该类库的控制台应用程序设置为x86

我可以成功加载同一供应商的其他 DLL 文件(也是 32 位)。

这是我的原生助手类:

class NativeHelper
{
    [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)]
    public static extern IntPtr LoadLibrary(string dllToLoad);

    [DllImport("kernel32.dll", EntryPoint = "LoadLibraryEx", SetLastError = true)]
    public static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr hFile, LoadLibraryFlags flags);

    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

    [DllImport("kernel32.dll")]
    public static extern bool FreeLibrary(IntPtr hModule);

    [System.Flags]
    public enum LoadLibraryFlags : uint
    {
        DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
        LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
        LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
        LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
        LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
        LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
        LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100,
        LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800,
        LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
    }
}

这就是我打电话的方式:

IntPtr pDll = NativeHelper.LoadLibrary(@"dhplay.dll"); // returns 0
if (pDll == IntPtr.Zero)
{
    var err = Marshal.GetLastWin32Error().ToString(); // returns 193
    Console.WriteLine(err);
}

我在这里缺少什么?如果我正在运行x86,为什么该 DLL 没有加载而其他人加载?

编辑(附加信息):

IntPtr.Size 是 4

dumpbin 返回8664 machine (x64) - 这意味着它是 64 位的?我检查了其他使用的 DLL,它们是 8664 machine (x86)

就依赖项而言,它正在我机器上的一个 vc++ 应用程序上运行。

【问题讨论】:

  • 为了确定,尝试打印IntPtr.Size...
  • 然后使用dumpbin(如果您使用Visual Studio 命令提示符,您应该在路径中包含它):dumpbin /headers yourdll.dll | more。第一行之一应该是machine (x86/x64)
  • 另一种可能性:您缺少对 dll 的一些依赖项...使用dependencywalker.com 查看您的 dll 使用的其他 dll 并检查它们是否已安装。也许您的 dll 正在使用您 PC 上没有的特定版本的 MSVCRT。
  • 不,他们不能。 VC++ 以 32 + 64 位运行什么 dll?请注意,系统 dll(kernel32、user32 和类似的)都是 32 位和 64 位。
  • 您确定没有设置任何 CPU 吗?

标签: c# c++ .net visual-c++ dll


【解决方案1】:

如果有烟,通常会发生火灾。某些 dll 可能是 x64,而您的应用程序是 x32(或相反)。

  • 签入您的应用程序IntPtr.Size。 4→x86,32位,8→x64,64位

  • 如果您使用 Visual Studio 命令提示符,您应该可以使用dumpbin。为您的 dll 执行 dumpbin /headers yourdll.dll | more。第一行之一应该是machine (...)。在(...) 中,如果它是 x86(所以 32 位)或 x64(所以 64 位),则应该写入

对于第二个问题,您不能以任何方式在单个进程中混合 32 位和 64 位 dll。一些程序“作弊”并创建具有正确位的辅助进程来加载 dll,然后在主进程和辅助进程之间进行 IPC(进程间通信)以使用 dll。显然它很复杂。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多