2017-05-06 11 views
2

GetModuleFileNameEx을 Java 응용 프로그램으로 가져 오려고합니다. 함수의 정의는 다음과 같습니다 나는이 같은 클래스에 정의java.lang.UnsatisfiedLinkError : 'GetModuleFileNameEx'함수를 찾는 동안 오류가 발생했습니다.

public abstract DWORD GetModuleFileNameEx(
    WinNT.HANDLE hProcess, 
    WinNT.HMODULE hModule, 
    char[] pathName, 
    WinNT.DWORD pathNameSize 
); 

:

DWORD WINAPI GetModuleFileNameEx(
    _In_  HANDLE hProcess, 
    _In_opt_ HMODULE hModule, 
    _Out_ LPTSTR lpFilename, 
    _In_  DWORD nSize 
); 

난에 그 번역

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.platform.win32.Kernel32; 
import com.sun.jna.platform.win32.WinDef; 
import com.sun.jna.platform.win32.WinNT; 
import com.sun.jna.win32.W32APIOptions; 


public abstract interface Kernel32Ext 
    extends Kernel32 
{ 
    public static final Kernel32Ext INSTANCE = (Kernel32Ext)Native.loadLibrary("kernel32.dll", Kernel32Ext.class, W32APIOptions.DEFAULT_OPTIONS); 
    public abstract DWORD GetModuleFileNameEx(WinNT.HANDLE hProcess, WinNT.HMODULE hModule, char[] pathName, WinNT.DWORD pathNameSize); 
} 

을하지만 난 메서드를 호출하려고 할 때 오류가 발생합니다 :

java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx': Uvedená procedura nebyla nalezena. 

ouble 체크 및 스택 오버 플로우 및 기타 JNA 프로그램의 게시물에 따라 LPTSTR은 JNA API에서 char[]으로 올바르게 변환됩니다. 그래서 뭔가 다른 것이 틀림 없습니다. 잘못된 dll을 가져 오거나 잘못된 옵션을 사용합니까?

Windows 7 x64 비트 (체코 어, 영어 이외의 오류 메시지)로 실행 중입니다.

+1

내 보낸 함수가 GetModuleFileNameExW입니다. 그건 자바 코드와 일치하는 유니 코드 변형입니다 [] –

+0

메모로; 내 자신의 kernel32를 검사했는데 Windows 10에서는'GetModuleFileNameExW'가 부족한 것으로 보이지만 psapi는 KernelBase와 함께 작동합니다. 같은 자바 매개 변수 유형, 그냥 다른 이름과 dll. –

+0

@jorn 이것은 모두 문서화되어 있습니다. –

답변

1

kernel32 (또는 다른 곳)에는 해당 이름의 기능이 없습니다. GetModuleFileNameEx에 대한 MSDN 페이지를 참조하십시오. 당신이 찾고있는 기능은 GetModuleFileNameExW입니다. 좋아

+0

정확하게 가져 오지만 대신 Psapi.dll에서 가져와야했습니다. –

+0

'W32APIOptions.DEFAULT_OPTIONS'에는'-A'와'-W' 접미사를 설명하는 함수 이름 매퍼가 포함되어 있습니다. 일반적으로'-A' 또는'-W'를 명시 적으로 표시하는 것은 부적절합니다. 함수 서명이 다른 경우에만 수행해야합니다 (일반적으로 문자 배열 유형을 중심으로 사용). – technomage

0

, 전체 코드 :

import com.sun.jna.Native; 
import com.sun.jna.platform.win32.WinDef; 
import com.sun.jna.platform.win32.WinNT; 
import com.sun.jna.win32.W32APIOptions; 

public interface Psapi extends WinNT { 
    public static final Psapi INSTANCE = (Psapi)Native.loadLibrary("Psapi.dll", Psapi.class, W32APIOptions.DEFAULT_OPTIONS); 
    public abstract WinDef.DWORD GetModuleFileNameExW(WinNT.HANDLE hProcess, WinNT.HMODULE hModule, char[] pathName, WinNT.DWORD pathNameSize); 
} 

주 내가 Psapi.dll을,하지의 Kernel32.dll에서 기능을 가져 끝났다.

사용 예제는 윈도우의 HWND를 부여하는 프로세스의 파일 이름을 얻을 수 있습니다 :

protected WinDef.HWND hwnd; 
    @Override 
    public String getProcessName() { 
    // Refference to int that will later be filled 
    IntByReference pid = new IntByReference(0); 
    // This function gives pid number to the second parameter passed by refference 
    UserExt.GetWindowThreadProcessId(hwnd, pid); 
    // Now get handle to the process 
    // 0x0400 | 0x0010 stands for reading info 
    // if you pass 0 you will get error 5 which stands for access denied 
    int pidVal = pid.getValue(); 
    HANDLE process = Kernel32.INSTANCE.OpenProcess(0x0400 | 0x0010, false, pidVal); 
    if(process==null) 
     throw new APIException("Winapi error: "+(Kernel32.INSTANCE.GetLastError())); 
    // Prepare buffer for characters, just as you would 
    // in goold 'ol C program 
    char[] path = new char[150]; 
    DWORD buffSize = new DWORD(path.length); 
    // The W at the end of the function name stands for WIDE - 2byte chars 
    Psapi.INSTANCE.GetModuleFileNameExW(process, null, path, buffSize); 
    // convert buffer to java string 
    return String.copyValueOf(path); 
    }