【问题标题】:Java JNA: GetProcAddress returns nullJava JNA:GetProcAddress 返回 null
【发布时间】:2016-08-04 20:45:58
【问题描述】:

以下代码找不到LoadLibraryW

private static FOREIGN_THREAD_START_ROUTINE getLoadLibraryWAddress() throws Win32Exception {
    HMODULE module = Kernel32.INSTANCE.GetModuleHandle("KERNEL32");
    if(module == null) {
        Win32Exception.throwWithLastError("Failed to find KERNEL32 module");
    }

    FOREIGN_THREAD_START_ROUTINE address = Kernel32MissingFunctions.INSTANCE.GetProcAddress(module, "LoadLibraryW");
    if(address == null) {
        Win32Exception.throwWithLastError("Failed to find LoadLibraryW in KERNEL32 module");
    }
    return address;
}

GetProcAddress 声明如下:

public interface Kernel32MissingFunctions extends StdCallLibrary {

    Kernel32MissingFunctions INSTANCE = (Kernel32MissingFunctions) Native.loadLibrary("kernel32",
            Kernel32MissingFunctions.class, W32APIOptions.UNICODE_OPTIONS);

    public static final int MEM_RELEASE = 0x8000;

    public LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int flAllocationType, int flProtect);

    public int VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int dwFreeType);

    public FOREIGN_THREAD_START_ROUTINE GetProcAddress(HMODULE hModule, String lpProcName);
}

有人知道为什么吗?我的错误是什么? 谢谢!

【问题讨论】:

  • GetProcAddress() 返回 null 时最后报告的错误是什么?你为什么要声明GetProcAddress() 来返回FOREIGN_THREAD_START_ROUTINE?这不是真正的GetProcAddress() 实际返回的内容。它返回一个FARPROC,它本质上只是一个指针,JNA 中的LPVOID 也是如此。然后,当您需要实际调用该函数时,您将对指针进行类型转换。
  • 您是否将 ANSI 字符串作为第二个参数传递给本机 GetProcAddress 调用?与其他 WIndows API funkcions 不同,GetProcAddress 没有 unicode 版本,因为导出函数的名称是使用 ANSI 字符编写的。

标签: java winapi jna kernel32 getprocaddress


【解决方案1】:

马丁·德拉布是对的。使用 W32APIOptions.UNICODE_OPTIONS 将 Unicode 字符串传递给 Ansi 函数。更改接口如下解决了问题:

public interface Kernel32MissingFunctions extends StdCallLibrary {

    Kernel32MissingFunctions INSTANCE = (Kernel32MissingFunctions) Native.loadLibrary("kernel32",
            Kernel32MissingFunctions.class, W32APIOptions.ASCII_OPTIONS);

    public static final int MEM_RELEASE = 0x8000;

    public LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int flAllocationType, int flProtect);

    public int VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int dwFreeType);

    public LPVOID GetProcAddress(HMODULE hModule, String lpProcName);
}

【讨论】:

    猜你喜欢
    • 2015-06-04
    • 2019-08-25
    • 2016-05-28
    • 2016-03-08
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多