正如@Etienne de Martel 所提到的,如果没有 JNA 或 JNI 的任何帮助,我们无法直接从 Java 中读取它......幸运的是,SO 上还有另一个 thread 为我指明了正确的方向...... .
我需要做的是:
public interface Kernel32Impl extends com.sun.jna.platform.win32.Kernel32 {
Kernel32Impl KERNEL_32 = Native.load("kernel32", Kernel32Impl.class, W32APIOptions.DEFAULT_OPTIONS);
HANDLE OpenFileMapping(int lfProtect, boolean bInherit, String lpName);
HANDLE OpenEvent(int i, boolean bManualReset, String lpName);
}
最后在 Kotlin 中
class WindowsService {
var lastError: Int = 0
private set
fun openMemoryMapFile(filename: String): WinNT.HANDLE? {
val memMapFile = Kernel32Impl.KERNEL_32.OpenFileMapping(WinNT.SECTION_MAP_READ, false, filename)
lastError = Kernel32Impl.KERNEL_32.GetLastError()
return memMapFile
}
fun closeHandle(handle: WinNT.HANDLE) {
Kernel32Impl.KERNEL_32.CloseHandle(handle)
}
fun mapViewOfFile(handle: WinNT.HANDLE?): Pointer? {
handle ?: return null
return Kernel32.INSTANCE.MapViewOfFile(handle, WinNT.SECTION_MAP_READ, 0, 0, 0)
}
fun unmapViewOfFile(pointer: Pointer) {
Kernel32Impl.KERNEL_32.UnmapViewOfFile(pointer)
lastError = Kernel32Impl.INSTANCE.GetLastError()
}
}
然后是那个的实际用法:
windowsService.openMemoryMapFile(MEMORY_MAP_FILE_NAME)?.let { handle ->
windowsService.mapViewOfFile(handle)?.let { pointer ->
val buffer = ByteBuffer.allocateDirect(BLOCK_SIZE)
buffer.put(pointer.getByteArray(0, BLOCK_SIZE))
buffer.order(ByteOrder.LITTLE_ENDIAN)
buffer.rewind()