Java FFM - 获取结构体数组字段的 var 句柄

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

我从第一原理开始使用 FFM 来访问本机结构,例如:

VkLayerProperties {
    char layerName[256];
    uint32_t specVersion;
    uint32_t implementationVersion;
    char description[256];
};

以下简单代码从给定的堆外内存地址中提取字段:

public void load(MemorySegment address) {
    var layout = MemoryLayout.structLayout(
        MemoryLayout.sequenceLayout(256, JAVA_BYTE).withName("layerName"),
        JAVA_INT.withName("specVersion"),
        JAVA_INT.withName("implementationVersion"),
        MemoryLayout.sequenceLayout(256, JAVA_BYTE).withName("description")
    );

    VarHandle handle = layout.varHandle(PathElement.groupElement("specVersion"));
    int specVersion = (int) handle.get(address, 0L);
    ....
}

这对于原始字段(以及引用类型)效果很好。 但是如何使用布局和路径元素的相同模式来创建两个 array 字段的 var 句柄呢? 我已经尝试了各种元素类的每种组合,尝试了

MethodHandles
中的帮助器等等,但都没有任何运气。

要么句柄因“不是值布局”错误而失败,要么

get
失败(大概)因为坐标错误。 我怀疑我只是比平常更愚蠢。

但是,如果查看使用

jextract
为该结构生成的等效代码,你会发现,它本质上只是硬编码了字节偏移量:

public class VkLayerProperties {
    public static MemorySegment layerName$slice(MemorySegment seg) {
        return seg.asSlice(0, 256);
    }
}

所有非数组字段都按预期使用句柄:

static final VarHandle const$1 = constants$53.const$0.varHandle(MemoryLayout.PathElement.groupElement("specVersion"));

public static int specVersion$get(MemorySegment seg) {
    return (int)constants$53.const$1.get(seg);
}

显然,我可以使用相同的方法并根据布局计算字节偏移量和大小(甚至只是对它们进行硬编码),但似乎使用路径元素框架是首选解决方案。

所以:

  1. 有没有办法通过从结构内存布局派生 var 句柄来访问 array 字段?

  2. 为什么等效的

    jextract
    绕过一般方法并在这些情况下使用内存切片。

这两个问题有联系吗?

请注意,“使用 jextract”不是答案。

预先感谢您的任何建议或解决方案。

java project-panama
1个回答
0
投票

看起来您正在搜索

MemoryLayout.PathElement.sequenceElement
,它接受结果
VarHandle
中的索引参数。

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