java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx'
java.lang.UnsatisfiedLinkError: Error looking up function 'GetModuleFileNameEx'
我正在尝试在 java 应用程序中导入 GetModuleFileNameEx
。函数的定义是:
DWORD WINAPI GetModuleFileNameEx(
_In_ HANDLE hProcess,
_In_opt_ HMODULE hModule,
_Out_ LPTSTR lpFilename,
_In_ DWORD nSize
);
我将其翻译成:
public abstract DWORD GetModuleFileNameEx(
WinNT.HANDLE hProcess,
WinNT.HMODULE hModule,
char[] pathName,
WinNT.DWORD pathNameSize
);
我在 class 中这样定义的:
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.
我仔细检查并根据此处关于堆栈溢出和其他 JNA 程序的帖子,LPTSTR
在 JNA API 中正确地转换为 char[]
。所以肯定还有别的地方不对劲。我是导入了错误的 dll,还是使用了错误的选项?
我是 运行 这个 Windows 7 x64 位(捷克语,因此是非英语错误消息)。
kernel32(或其他地方)中没有该名称的函数。请参阅 GetModuleFileNameEx 的 MSDN 页面。您要查找的函数是 GetModuleFileNameExW
.
好的,完整代码:
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 导入了函数。
示例用法,获取给定 window 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);
}
我正在尝试在 java 应用程序中导入 GetModuleFileNameEx
。函数的定义是:
DWORD WINAPI GetModuleFileNameEx(
_In_ HANDLE hProcess,
_In_opt_ HMODULE hModule,
_Out_ LPTSTR lpFilename,
_In_ DWORD nSize
);
我将其翻译成:
public abstract DWORD GetModuleFileNameEx(
WinNT.HANDLE hProcess,
WinNT.HMODULE hModule,
char[] pathName,
WinNT.DWORD pathNameSize
);
我在 class 中这样定义的:
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.
我仔细检查并根据此处关于堆栈溢出和其他 JNA 程序的帖子,LPTSTR
在 JNA API 中正确地转换为 char[]
。所以肯定还有别的地方不对劲。我是导入了错误的 dll,还是使用了错误的选项?
我是 运行 这个 Windows 7 x64 位(捷克语,因此是非英语错误消息)。
kernel32(或其他地方)中没有该名称的函数。请参阅 GetModuleFileNameEx 的 MSDN 页面。您要查找的函数是 GetModuleFileNameExW
.
好的,完整代码:
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 导入了函数。
示例用法,获取给定 window 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);
}