java 将JNA代码移植到外部函数和内存API(FFM),从C库返回的String[]失败[已关闭]

46scxncf  于 2023-02-07  发布在  Java
关注(0)|答案(1)|浏览(85)

这个问题是由打字错误或无法再重现的问题引起的。虽然类似的问题在这里可能是on-topic,但这个问题的解决方式不太可能帮助未来的读者。
昨天关门了。
Improve this question
将JNA代码移植到外部函数和内存API(FFM)(Java 19、JEP 424)时,从C#返回的String []数组失败
C API:

int nc_get_att_string(  
        int          ncid,
        int          varid,
        const char * name,
        char **      value)

请注意,与大多数其他nc_get_att函数不同,nc_get_att_string()分配的内存块将返回给调用函数。必须使用nc_free_string()专门释放此内存块,以避免任何内存泄漏。另请注意,您仍必须预分配传递给nc_get_att_string()的指针数组所需的内存。
因此,我们传递一个char * 指针数组,然后库返回一个字符串数组。我在Java中的JNA中使用了以下代码:

String[] valss = new String[len];
      ret = nc4.nc_get_att_string(grpid, varid, attname, valss);
      if (ret != 0)
        throw new IOException(ret + ": " + nc4.nc_strerror(ret));
      return valss;

但尝试在Kotlin的外部函数和内存API中执行等效操作失败:

val strings_p : MemorySegment = session.allocateArray(ValueLayout.ADDRESS, nelems)
        checkErr("nc_get_att_string", nc_get_att_string(grpid, varid, attname, strings_p))
        val result = mutableListOf<String>()
        for (i in 0 until nelems) {
            val s2 : MemoryAddress = strings_p.getAtIndex(ValueLayout.ADDRESS, i) 
            val s = s2.getUtf8String(0)  // FAILS here
            result.add(s)
        }
        return result

失败:

Symbol is NULL: MemoryAddress{ offset=0x0 }
java.lang.IllegalArgumentException: Symbol is NULL: MemoryAddress{ offset=0x0 }
    at java.base/jdk.internal.foreign.abi.SharedUtils.checkAddressable(SharedUtils.java:344)
    at java.base/jdk.internal.foreign.abi.SharedUtils.checkAddress(SharedUtils.java:338)
    at java.base/jdk.internal.foreign.MemoryAddressImpl.getUtf8String(MemoryAddressImpl.java:107)
    at sunya.cdm.netcdfClib.NCheader.readAttributeValues(NCheader.kt:365)

有人知道我哪里做错了吗?

5uzkadbs

5uzkadbs1#

问题出在安装的C库上,JNA代码看到了同样的东西。抱歉误导了。

相关问题