2016-08-04 3 views
0

Le code suivant ne parvient pas à trouver LoadLibraryWJava JNA: GetProcAddress retourne null

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

où GetProcAddress est déclarée comme suit:

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

Est-ce que quelqu'un sait pourquoi? Quelle est mon erreur? Merci!

+0

Quelle est la dernière erreur signalée lorsque 'GetProcAddress()' renvoie null? Et pourquoi déclarez-vous 'GetProcAddress()' pour retourner un 'FOREIGN_THREAD_START_ROUTINE'? Ce n'est PAS ce que le vrai 'GetProcAddress()' renvoie réellement. Il renvoie un 'FARPROC', qui est essentiellement juste un pointeur, et serait donc' LPVOID' dans la JNA. Vous tapez alors le pointeur lorsque vous devez réellement appeler la fonction. –

+4

Transmettez-vous une chaîne ANSI en tant qu'argument seciond à l'appel natif 'GetProcAddress'? Contrairement aux autres funkcions de l'API WIndows, 'GetProcAddress' n'a pas de version Unicode car les noms des fonctions exportées sont écrits en utilisant des caractères ANSI. –

Répondre

0

Martin Drab avait raison. L'utilisation de W32APIOptions.UNICODE_OPTIONS a transmis une chaîne Unicode à la fonction Ansi. La modification des interfaces suivantes a corrigé le problème:

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