Kotlin:创建并引用真正的Java数组(用于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类,因为它不知道如何映射它。有没有一种方法可以引用真正的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的数组(请参阅文档)。

您可以手动构建一个指针缓冲区并传递:

Pointer modules = new Memory(Pointer.SIZE * length);
int offset = 0;
for (h: hmodules) {
    modules.setPointer(Pointer.SIZE * offset, h.getPointer())
    offset += 1;
}

相关内容

  • 没有找到相关文章

最新更新