2016-08-04 11 views
0

Следующий код не удается найти LoadLibraryWJava ЮНА: GetProcAddress возвращает нуль

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); 
} 

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

+0

Какая последняя ошибка сообщается, когда 'GetProcAddress()' возвращает значение null? И почему вы объявляете 'GetProcAddress()' для возврата 'FOREIGN_THREAD_START_ROUTINE'? Это НЕ то, что фактически возвращает GetProcAddress() '. Он возвращает 'FARPROC', который по существу является только указателем, и поэтому будет' LPVOID' в JNA. Затем вы набираете тип указателя, когда вам нужно фактически вызвать функцию. –

+4

Вы передаете строку ANSI в качестве аргумента seciond для собственного вызова GetProcAddress? В отличие от других функций API WIndows, 'GetProcAddress' не имеет юникодной версии, так как имена экспортируемых функций записываются с использованием символов ANSI. –

ответ

0

Martin Drab был прав. Использование 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); 
}