Java JNA: GetProcAddress возвращает значение null

Следующий код не может найти 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);
}

Кто-нибудь знает, почему? В чем моя ошибка? Спасибо!


person Ethon    schedule 04.08.2016    source источник
comment
О какой последней ошибке сообщается, когда GetProcAddress() возвращает значение null? И почему вы объявляете, что GetProcAddress() возвращает FOREIGN_THREAD_START_ROUTINE? Это НЕ то, что на самом деле возвращает настоящий GetProcAddress(). Он возвращает FARPROC, который по сути является просто указателем, и поэтому в JNA будет LPVOID. Затем вы должны ввести указатель, когда вам действительно нужно вызвать функцию.   -  person Remy Lebeau    schedule 05.08.2016
comment
Вы передаете строку ANSI в качестве второго аргумента собственному вызову GetProcAddress? В отличие от других функций WIndows API, GetProcAddress не имеет версии Unicode, поскольку имена экспортируемых функций записываются с использованием символов ANSI.   -  person Martin Drab    schedule 05.08.2016


Ответы (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);
}
person Ethon    schedule 07.08.2016