Kotlin:创建并引用真正的 Java 数组(针对 JNA)
Kotlin: Create and refer true Java arrays (for JNA)
我正在尝试将 JNA 与 Kotlin 结合使用,但 运行 遇到了问题。 Caused by: java.lang.IllegalArgumentException: class [Lcom.sun.jna.platform.win32.WinDef$HMODULE; is not a supported argument type (in method EnumProcessModulesEx in class kotmem.unsafe.Psapi)
我的 Psapi
直接映射对象:
package kotmem.unsafe
import com.sun.jna.*
import com.sun.jna.platform.win32.*
import com.sun.jna.ptr.*
object Psapi {
// note Array<WinDef.HMODULE?>
external fun EnumProcessModulesEx(process: Pointer, modules: Array<WinDef.HMODULE?>, cb: Int,
neededModules: IntByReference, flags: Int): Boolean
external fun GetModuleInformation(process: Pointer, module: WinDef.HMODULE, moduleInfo: LPMODULEINFO, cb: Int): Boolean
external fun GetModuleBaseNameA(process: Pointer, module: WinDef.HMODULE, fileName: ByteArray, size: Int): Int
init {
Native.register(NativeLibrary.getInstance("Psapi"))
}
}
问题似乎出在我的调用方式上。 JNA 不喜欢 Kotlin 的 Array
class 我假设是因为它不知道如何映射。有没有办法引用真正的 Java 数组,以便 JNA 可以映射此函数?另外,有没有办法构造这样的?
我是这样称呼它的:
fun modulesOfProcess(process: UnsafeProcess): List<UnsafeModule> {
val list = emptyList<UnsafeModule>()
val process = process.handle.pointer
// note that I construct using arrayOfNulls
val modules = arrayOfNulls<WinDef.HMODULE>(1024)
val needed = IntByReference()
Psapi.EnumProcessModulesEx(process, modules, modules.size, needed, 1)
for (i in 0..needed.value / 4) {
val module = modules[i] ?: continue
val info = LPMODULEINFO()
if (!Psapi.GetModuleInformation(process, module, info, info.size()))
list + UnsafeModule(module, info)
}
return list
}
直接映射不支持Pointer
数组或NativeMapped
数组(see docs)。
您可以手动构造一个指针缓冲区并传递它:
Pointer modules = new Memory(Pointer.SIZE * length);
int offset = 0;
for (h: hmodules) {
modules.setPointer(Pointer.SIZE * offset, h.getPointer())
offset += 1;
}
我正在尝试将 JNA 与 Kotlin 结合使用,但 运行 遇到了问题。 Caused by: java.lang.IllegalArgumentException: class [Lcom.sun.jna.platform.win32.WinDef$HMODULE; is not a supported argument type (in method EnumProcessModulesEx in class kotmem.unsafe.Psapi)
我的 Psapi
直接映射对象:
package kotmem.unsafe
import com.sun.jna.*
import com.sun.jna.platform.win32.*
import com.sun.jna.ptr.*
object Psapi {
// note Array<WinDef.HMODULE?>
external fun EnumProcessModulesEx(process: Pointer, modules: Array<WinDef.HMODULE?>, cb: Int,
neededModules: IntByReference, flags: Int): Boolean
external fun GetModuleInformation(process: Pointer, module: WinDef.HMODULE, moduleInfo: LPMODULEINFO, cb: Int): Boolean
external fun GetModuleBaseNameA(process: Pointer, module: WinDef.HMODULE, fileName: ByteArray, size: Int): Int
init {
Native.register(NativeLibrary.getInstance("Psapi"))
}
}
问题似乎出在我的调用方式上。 JNA 不喜欢 Kotlin 的 Array
class 我假设是因为它不知道如何映射。有没有办法引用真正的 Java 数组,以便 JNA 可以映射此函数?另外,有没有办法构造这样的?
我是这样称呼它的:
fun modulesOfProcess(process: UnsafeProcess): List<UnsafeModule> {
val list = emptyList<UnsafeModule>()
val process = process.handle.pointer
// note that I construct using arrayOfNulls
val modules = arrayOfNulls<WinDef.HMODULE>(1024)
val needed = IntByReference()
Psapi.EnumProcessModulesEx(process, modules, modules.size, needed, 1)
for (i in 0..needed.value / 4) {
val module = modules[i] ?: continue
val info = LPMODULEINFO()
if (!Psapi.GetModuleInformation(process, module, info, info.size()))
list + UnsafeModule(module, info)
}
return list
}
直接映射不支持Pointer
数组或NativeMapped
数组(see docs)。
您可以手动构造一个指针缓冲区并传递它:
Pointer modules = new Memory(Pointer.SIZE * length);
int offset = 0;
for (h: hmodules) {
modules.setPointer(Pointer.SIZE * offset, h.getPointer())
offset += 1;
}