JDK 17 外部内存 API 抛出异常 - 方法抛出 'java.lang.UnsatisfiedLinkError' 异常

JDK 17 Foreign memory API throws exception - Method threw 'java.lang.UnsatisfiedLinkError' exception

我正在尝试使用 JDK 17.0.1 执行以下代码。我确保 JDK 17 在 class 路径上。

这是我正在执行的代码:

import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;


import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;

public class PanamaMain {
    public static void main (String[] args) {
        MemoryAddress address = MemorySegment.allocateNative(4, ResourceScope.newImplicitScope()).address();

        VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());

        int value = (int) handle.get(address); //This line throws the exception mentioned above.

        System.out.println("Memory Value: " + value);
    }
}

异常原因是:java.lang.UnsatisfiedLinkError:'java.lang.Object java.lang.invoke.VarHandle.get(java.lang.Object[])'

异常详情

我看到一些关于建议使用 java.library.path 系统 属性 的类似异常的回复,但我得到一个错误,指出 java.library.path 是一个无效标志。

非常感谢您在这个问题上的 help/tips!预先感谢您的宝贵时间!

VarHandle.get 方法需要 MemorySegment(不是 MemoryAddress)和段内的字节偏移量。标准 C 类型的布局在 CLinker.C_XXX 中找到,因此您不需要将 int 的字节大小硬编码为 4.

假设您的 PATH 对于启动 JDK17 是正确的,那么这应该可以工作:

MemorySegment segment = MemorySegment.allocateNative(CLinker.C_INT, ResourceScope.newImplicitScope());
VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
handle.set(segment, 0, 4567);
int value = (int)handle.get(segment, 0);
System.out.println("Memory Value: " + value + " = 0x"+Integer.toHexString(value));

打印:

Memory Value: 4567 = 0x11d7

在 JDK17 中,您还可以使用 MemoryAccess 从分配的 MemorySegment 中设置或获取值。 ,并且可以更改为:

MemorySegment segment = MemorySegment.allocateNative(CLinker.C_INT, ResourceScope.newImplicitScope());
MemoryAccess.setInt(segment, -1234);
int value = MemoryAccess.getInt(segment);
System.out.println("Memory Value: " + value + " = 0x"+Integer.toHexString(value));

版画

Memory Value: -1234 = 0xfffffb2e

请注意 API 已更改,因此 JDK18+ 中的等效代码将有所不同。