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+ 中的等效代码将有所不同。
我正在尝试使用 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+ 中的等效代码将有所不同。