I want to use libimobiledevice by Java Foreign API, This is my code, written by Kotlin:
class Device {
private val arena: Arena = Arena.openConfined()
private val udidAddress: MemorySegment = arena.allocate(C_POINTER)
private val deviceAddress: MemorySegment = arena.allocate(C_POINTER)
init {
if (idevice_new_with_options(deviceAddress, NULL(), IDEVICE_LOOKUP_USBMUX()) != IDEVICE_E_SUCCESS()) {
throw Exception("ERROR: No device found!")
}
if (idevice_get_udid(deviceAddress, udidAddress) != IDEVICE_E_SUCCESS()) {
idevice_free(deviceAddress)
throw Exception("ERROR: Get UDID failed")
} else {
println("connected")
println(MemorySegment.ofAddress(udidAddress.address()).getUtf8String(0))
}
}
}
fun main() {
Device()
}
But it got error while getting udid:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Out of bound access on segment MemorySegment{ array: Optional.empty address:140202431639472 limit: 0 }; new offset = 0; new length = 1
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.outOfBoundException(AbstractMemorySegmentImpl.java:371)
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.apply(AbstractMemorySegmentImpl.java:357)
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.apply(AbstractMemorySegmentImpl.java:70)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:124)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:448)
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.checkBounds(AbstractMemorySegmentImpl.java:346)
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.checkAccess(AbstractMemorySegmentImpl.java:311)
at java.base/java.lang.invoke.VarHandleSegmentAsBytes.checkAddress(VarHandleSegmentAsBytes.java:81)
at java.base/java.lang.invoke.VarHandleSegmentAsBytes.get(VarHandleSegmentAsBytes.java:108)
at java.base/java.lang.foreign.MemorySegment.get(MemorySegment.java:1388)
at java.base/jdk.internal.foreign.abi.SharedUtils.strlen(SharedUtils.java:199)
at java.base/jdk.internal.foreign.abi.SharedUtils.toJavaStringInternal(SharedUtils.java:190)
at java.base/java.lang.foreign.MemorySegment.getUtf8String(MemorySegment.java:890)
at Device.<init>(Device.kt:21)
at DeviceKt.main(Device.kt:27)
at DeviceKt.main(Device.kt)
The C language code i want:
static char *udid = NULL;
/* Device Handle */
idevice_t device = NULL;
/* Try to connect to first USB device */
if (idevice_new_with_options(&device, NULL, IDEVICE_LOOKUP_USBMUX) != IDEVICE_E_SUCCESS) {
printf("ERROR: No device found!\n");
return -1;
}
/* Retrieve the udid of the connected device */
if (idevice_get_udid(device, &udid) != IDEVICE_E_SUCCESS) {
printf("ERROR: Unable to get the device UDID.\n");
idevice_free(device);
return -1;
}
/* Outputs device identifier */
printf("Connected with UDID: %s\n", udid);
how to solve this problem? (sorry, this is my first time using stackoverflow)
It should return a udid, but I got an error, the code I tried is above.
It worked when I write like this:
class Device {
private var device: MemorySegment
private var udid: MemorySegment
init {
Arena.openConfined().use { arena ->
val udidAddress: MemorySegment = arena.allocate(C_POINTER)
val deviceAddress: MemorySegment = arena.allocate(C_POINTER)
if (idevice_new_with_options(deviceAddress, NULL(), IDEVICE_LOOKUP_USBMUX()) != IDEVICE_E_SUCCESS()) {
throw Exception("ERROR: No device found!")
}
device = deviceAddress.get(C_POINTER, 0)
if (idevice_get_udid(deviceAddress, udidAddress) != IDEVICE_E_SUCCESS()) {
idevice_free(deviceAddress)
throw Exception("ERROR: Get UDID failed")
}
udid = udidAddress.get(C_POINTER, 0).get(C_POINTER, 0)
println("connected")
println(udid.getUtf8String(0))
}
}
}