Kotlin JNA声明字段名称为空列表

问题描述 投票:1回答:1

下面的代码受this answerthis answer的启发很大,我正在尝试使其与Kotlin语言一起工作,而不是与答案中给出的Java一起工作。

它基本上基于JNA(Java本机访问),它实际上是从Windows本机库(在C ++上)提取SYSTEM_BATTERY_STATE以获得有关笔记本电脑电池的信息。

代码在Java版本中按预期工作,但是如果我尝试对Kotlin进行相同操作,则会出现异常,说明声明的字段名称是空列表/数组。

fun main() { getBatteryState() }

fun getBatteryState(): SYSTEM_BATTERY_STATE? {
    val batteryState = SYSTEM_BATTERY_STATE()
    val retrieveValue = PowrProf.CallNtPowerInformation(
        5,
        Pointer.NULL,
        0,
        batteryState,
        batteryState.size().toLong()
    )

    return if (retrieveValue == 0) batteryState else null
}

interface PowrProf : StdCallLibrary {
    @Suppress("FunctionName")
    fun CallNtPowerInformation(informationLevel: Int, inBuffer: Pointer?, inBufferLen: Long, outBuffer: SYSTEM_BATTERY_STATE?, outBufferLen: Long): Int

    companion object : PowrProf by Native.load("PowrProf", PowrProf::class.java)!!
}

class SYSTEM_BATTERY_STATE : Structure(ALIGN_MSVC), Structure.ByReference {
    var AcOnLine: Byte = 0
    var BatteryPresent: Byte = 0
    var Charging: Byte = 0
    var Discharging: Byte = 0

    var Spare1_0: Byte = 0
    var Spare1_1: Byte = 0
    var Spare1_2: Byte = 0
    var Spare1_3: Byte = 0

    var MaxCapacity = 0
    var RemainingCapacity = 0
    var Rate = 0

    var EstimatedTime = 0
    var DefaultAlert1 = 0
    var DefaultAlert2 = 0

    override fun getFieldOrder(): List<String> {
        return listOf(
            "AcOnLine", "BatteryPresent", "Charging", "Discharging",
            "Spare1_0", "Spare1_1", "Spare1_2", "Spare1_3",
            "MaxCapacity", "RemainingCapacity", "Rate",
            "EstimatedTime", "DefaultAlert1", "DefaultAlert2"
        )
    }
}
Exception in thread "main" java.lang.Error: Structure.getFieldOrder() on class com.animeshz.github.batteryinfo.SYSTEM_BATTERY_STATE returns names ([AcOnLine, BatteryPresent, Charging, DefaultAlert1, DefaultAlert2, Discharging, EstimatedTime, MaxCapacity, Rate, RemainingCapacity, Spare1_0, Spare1_1, Spare1_2, Spare1_3]) which do not match declared field names ([])
    at com.sun.jna.Structure.getFields(Structure.java:1089)
    at com.sun.jna.Structure.deriveLayout(Structure.java:1232)
    at com.sun.jna.Structure.calculateSize(Structure.java:1159)
    at com.sun.jna.Structure.calculateSize(Structure.java:1111)
    at com.sun.jna.Structure.allocateMemory(Structure.java:414)
    at com.sun.jna.Structure.<init>(Structure.java:205)
    at com.sun.jna.Structure.<init>(Structure.java:193)
    at com.sun.jna.Structure.<init>(Structure.java:180)
    at com.animeshz.github.batteryinfo.SYSTEM_BATTERY_STATE.<init>(SYSTEM_BATTERY_STATE.kt:9)
    at com.animeshz.github.batteryinfo.UtilKt.getBatteryState(util.kt:11)
    at com.animeshz.github.batteryinfo.UtilKt.main(util.kt:60)
    at com.animeshz.github.batteryinfo.UtilKt.main(util.kt)

为什么声明的字段名出来的是空数组/列表?而我该如何解决呢?

java kotlin struct jna
1个回答
2
投票

JNA的Structure类使用反射来查找字段名称,这意味着必须将其声明为public字段/属性。由于您不能直接在Kotlin中执行此操作,因此需要通过声明以下字段来解决此问题:

class SYSTEM_BATTERY_STATE(
    @JvmField var AcOnLine: Byte = 0, 
    @JvmField var BatteryPresent: Byte = 0, 
    (and so on) : Structure() {

    override fun getFieldOrder() // like you have it

}
© www.soinside.com 2019 - 2024. All rights reserved.