我有一个本机
.so
库,具有以下功能:
void foo(void* handle);
它在 C# 中运行良好:
[DllImport("library.so", CallingConvention = (CallingConvention) 3)]
private static extern void foo(ref IntPtr handle);
// ...
IntPtr handle = IntPtr.Zero;
foo(ref handle);
但是,我无法使用 FFM API 在 Java 22 中实现它:
var LINKER = Linker.nativeLinker();
var SYM_LOOKUP = SymbolLookup.loaderLookup().or(LINKER.defaultLookup());
var FOO = LINKER.downcallHandle(SYM_LOOKUP.find("foo").orElseThrow(), FunctionDescriptor.ofVoid(ADDRESS));
var handle = Arena.global().allocate(ValueLayout.ADDRESS); // is this correct?
FOO.invokeExact(handle);
由于某种原因,我在本机代码中得到
std::bad_array_new_length
(不幸的是,我没有本机库的源代码)。
JNA中有
com.sun.jna.ptr.IntByReference
,FFM API中有类似的东西吗?
我发现了错误。实际上我有 2 个本机方法:
void initHandle(void* handle);
void useHandle(void* handle);
我需要初始化句柄然后使用它。我正在这样做:
var handle = Arena.global().allocate(ValueLayout.ADDRESS);
INIT_HANDLE.invokeExact(handle);
USE_HANDLE.invokeExact(handle);
事实证明,我必须在第二个函数中以不同的方式传递句柄:
var handle = Arena.global().allocate(ValueLayout.ADDRESS);
INIT_HANDLE.invokeExact(handle);
USE_HANDLE.invokeExact(handle.get(ADDRESS, 0));