Kotlin JNA 获取声明的字段名称为空列表
Kotlin JNA getting declared field names to be empty list
下面的代码受到 this answer and 的高度启发,我试图让它与 Kotlin 语言一起工作,而不是那里的答案中给出的 Java。
它基本上基于 JNA(Java Native Access),它本质上是从 Windows Native 库(在 C++ 上)中提取 SYSTEM_BATTERY_STATE 以获取有关电池的信息笔记本电脑。
代码在 Java 版本中按预期工作,但如果我尝试对 Kotlin 执行相同的操作,我会收到一个异常,指出声明的字段名称为空 list/array。
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)
为什么声明的字段名称是空的array/list?我该如何解决这个问题?
JNA 的 Structure
class 使用反射来查找字段名称,这意味着它们必须声明为 public
fields/attributes。 @JvmField
annotation in Kotlin 删除吸气剂并根据需要公开这些属性。我怀疑这对你有用(未经测试):
class SYSTEM_BATTERY_STATE(
@JvmField var AcOnLine: Byte = 0,
@JvmField var BatteryPresent: Byte = 0,
@JvmField var Charging: Byte = 0,
@JvmField var Discharging: Byte = 0,
@JvmField var Spare1_0: Byte = 0,
@JvmField var Spare1_1: Byte = 0,
@JvmField var Spare1_2: Byte = 0,
@JvmField var Spare1_3: Byte = 0,
@JvmField var MaxCapacity = 0,
@JvmField var RemainingCapacity = 0,
@JvmField var Rate = 0,
@JvmField var EstimatedTime = 0,
@JvmField var DefaultAlert1 = 0,
@JvmField var DefaultAlert2 = 0
) : Structure(ALIGN_MSVC), Structure.ByReference {
override fun getFieldOrder() = listOf(
"AcOnLine", "BatteryPresent", "Charging", "Discharging",
"Spare1_0", "Spare1_1", "Spare1_2", "Spare1_3",
"MaxCapacity", "RemainingCapacity", "Rate",
"EstimatedTime", "DefaultAlert1", "DefaultAlert2"
)
}
下面的代码受到 this answer and
它基本上基于 JNA(Java Native Access),它本质上是从 Windows Native 库(在 C++ 上)中提取 SYSTEM_BATTERY_STATE 以获取有关电池的信息笔记本电脑。
代码在 Java 版本中按预期工作,但如果我尝试对 Kotlin 执行相同的操作,我会收到一个异常,指出声明的字段名称为空 list/array。
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)
为什么声明的字段名称是空的array/list?我该如何解决这个问题?
JNA 的 Structure
class 使用反射来查找字段名称,这意味着它们必须声明为 public
fields/attributes。 @JvmField
annotation in Kotlin 删除吸气剂并根据需要公开这些属性。我怀疑这对你有用(未经测试):
class SYSTEM_BATTERY_STATE(
@JvmField var AcOnLine: Byte = 0,
@JvmField var BatteryPresent: Byte = 0,
@JvmField var Charging: Byte = 0,
@JvmField var Discharging: Byte = 0,
@JvmField var Spare1_0: Byte = 0,
@JvmField var Spare1_1: Byte = 0,
@JvmField var Spare1_2: Byte = 0,
@JvmField var Spare1_3: Byte = 0,
@JvmField var MaxCapacity = 0,
@JvmField var RemainingCapacity = 0,
@JvmField var Rate = 0,
@JvmField var EstimatedTime = 0,
@JvmField var DefaultAlert1 = 0,
@JvmField var DefaultAlert2 = 0
) : Structure(ALIGN_MSVC), Structure.ByReference {
override fun getFieldOrder() = listOf(
"AcOnLine", "BatteryPresent", "Charging", "Discharging",
"Spare1_0", "Spare1_1", "Spare1_2", "Spare1_3",
"MaxCapacity", "RemainingCapacity", "Rate",
"EstimatedTime", "DefaultAlert1", "DefaultAlert2"
)
}