Java Foreign API从C_POINTER获取UDID报错,如何解决?
解决Java Foreign API调用libimobiledevice获取UDID的IndexOutOfBoundsException问题
错误原因
你的错误源于对C指针在Java Foreign API中的处理逻辑理解偏差:
- 在目标C代码中,
idevice_get_udid(device, &udid)是将UDID字符串的指针赋值给udid(传入的是char**类型的指针)。 - 你的Kotlin代码中,
udidAddress是分配的C_POINTER类型内存段(对应C的char**),但你直接用udidAddress.address()获取的是这个指针变量自身的内存地址,而非它指向的UDID字符串的地址,导致后续读取字符串时访问了无效内存区域,触发IndexOutOfBoundsException。 - 此外,原代码中
idevice_free(deviceAddress)的调用也有误,应该传入deviceAddress内部存储的设备指针,而非deviceAddress本身。
修正方案
需要从udidAddress中读取它存储的实际指针值(对应C中*udid的地址),再用这个地址创建MemorySegment读取UDID字符串;同时修正idevice_free的调用参数。
修正后的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()) { // 读取deviceAddress中存储的设备指针,再传递给idevice_free val devicePtr = deviceAddress.get(C_POINTER, 0) idevice_free(devicePtr) throw Exception("ERROR: Get UDID failed") } else { println("connected") // 从udidAddress中读取指向UDID字符串的指针 val udidPtr = udidAddress.get(C_POINTER, 0) // 用该指针创建MemorySegment并读取UTF-8字符串 println(udidPtr.getUtf8String(0)) } } } fun main() { Device() }
补充说明
- 如果没有显式定义
C_POINTER,可以用ValueLayout.ADDRESS替代,两者均对应C语言中的指针类型。 - 根据libimobiledevice官方文档,
idevice_get_udid返回的UDID字符串由库内部管理,无需手动释放;但设备指针必须在使用完毕后调用idevice_free释放,修正后的代码已处理此逻辑。
内容的提问来源于stack exchange,提问作者purofle
相关产品推荐
相关产品推荐

