我想通过FFI/巴拿马从Java访问PKCS11图书馆.假设我们在Windows x64下有以下打包的组布局:

GroupLayout groupLayout = MemoryLayout.structLayout(
    MemoryLayout.sequenceLayout(64, JAVA_BYTE).withName("slotDescription"),
    MemoryLayout.sequenceLayout(32, JAVA_BYTE).withName("manufacturerId"),
    JAVA_INT_UNALIGNED.withName("flags"),
    MemoryLayout.structLayout(
        JAVA_BYTE.withName("major"),
        JAVA_BYTE.withName("minor")
    ).withName("hardwareVersion"),
    MemoryLayout.structLayout(
        JAVA_BYTE.withName("major"),
        JAVA_BYTE.withName("minor")
    ).withName("firmwareVersion")
).withName("CK_SLOT_INFO");

一个简单的方法是写一个helper方法:

public static String getString(MemorySegment memorySegment, int offset, int length) {
    byte[] slicedData = new byte[length];
    MemorySegment slicedMemorySegment = memorySegment.asSlice(offset, length);
    slicedMemorySegment.asByteBuffer().get(slicedData);
    return new String(slicedData);
}

然后使用偏移量和长度调用它:

String manufacturerId = MemorySegmentUtils.getString(memorySegment, 64, 32);

因为PKCS11使用不同的填充/填充,所以我不想硬编码这些偏移量和长度.像在Java VarHandle to a C string with java.lang.foreign API中提到的那样使用getUtf8String是不起作用的,因为字符字符串是固定的,并且不是以零结尾.

那么,我如何使用MethodHandle来读取这些字节:

MethodHandle methodHandle = groupLayout.sliceHandle(MemoryLayout.PathElement.groupElement("manufacturerId"));

// What to do now?
String manufacturerId = ???

推荐答案

解决方案如下所示:

public static String getFixedString(MemorySegment memorySegment, GroupLayout groupLayout, String name) throws Throwable {
    MethodHandle methodHandle = groupLayout.sliceHandle(MemoryLayout.PathElement.groupElement(name));
    MemorySegment namedMemorySegment = (MemorySegment) methodHandle.invokeExact(memorySegment);
    byte[] namedData = namedMemorySegment.toArray(ValueLayout.JAVA_BYTE);
    return new String(namedData);
}

Java相关问答推荐

收听RDX中用户数据的变化

我可以从Java模块中排除maven资源文件夹吗?

Java事件系统通用转换为有界通配符

无法找到符号错误—Java—封装

Java List with all combinations of 8 booleans

有关手动创建的包的问题

使用@MappdSuperClass扩展ParentClass&Won t继承ParentClass属性

如何获得执行人?

在AVL树的Remove方法中使用NoSuchElementException时遇到问题

更新GWT 2.5.1到2.11.0和sencha GXT 3.1.1到4.1时出现错误

内存和硬盘中的Zip不同,这会导致下载后的Zip损坏

允许同时执行两个方法,但不能同时执行这两个方法

Oj算法 MatrixR032从字符串、归一化和余弦相似度计算创建

JFree Chart从图表中删除边框

在缺少字段时使用Jackson With Options生成Optional.Empty()

Win32函数的JNA绑定DwmGetColorizationColor返回E_INVALIDARG错误

我该如何为我的类编写getter和setter方法?

在权限列表中找不到我的应用程序

验证没有';t work on Hibernate Entity';s字段

Java泛型方法重载