如何通过 java 外部内存 api 传递值指针

How to pass over a value pointer via java foreign memory api

我想在 C 中调用以下方法(已定义 here):

heif_image_handle* handle;
heif_context_get_primary_image_handle(ctx, &handle);

我遇到的问题是我无法通过 C-API 访问结构 heif_image_handleIt is defined as a struct without a definition:

struct heif_image_handle;

我尝试过的:

try (var scope = ResourceScope.newSharedScope()) {
    MemoryAddress heif_context_alloc = heif_context_alloc();
    // ...
    MemoryAddress primary_image_handle = MemorySegment.allocateNative(C_POINTER, scope).address();
    heif_context_get_primary_image_handle(scope, primary_image_handle.address(), heif_context_alloc);
    // ...
}

谁能帮助我如何将此方法用于巴拿马 API。我实际的解决方法是扩展 C-API 但原作者不想那样做。

我的实际代码如下:https://github.com/lanthale/LibHeifFX/blob/main/LibHeifFX/src/main/java/org/libheiffx/LibheifImage.java

你的代码对我来说几乎是正确的。您只需要保留分配的段(代表 heif_image_handle**),然后在调用 heif_context_get_primary_image_handle 之后,在库将主图像句柄设置为之后从该段检索 MemoryAddress它(使用 JDK 17 API 的示例):

// allocate blob of memory the size of a pointer
MemorSegment primary_image_handle_seg = MemorySegment.allocateNative(C_POINTER);
// call library to set the handle into the allocated memory
heif_context_get_primary_image_handle(ctx, primary_image_handle_seg.address());
// retrieve pointer from allocated memory
MemoryAddress primary_image_handle = MemoryAccess.getAddress(primary_image_handle_seg);

一般来说,像在 C 中那样进行堆栈分配并获取分配值的地址,如您显示的代码片段中那样,直接在 Java 中是不可能的。所以,就巴拿马外国 API 而言,每当你在 C 代码中看到这样的东西时:

some_type* val;

您需要为其分配一个MemorySegment

// some_type** val_ptr;
MemorySegment val_ptr = MemerySegment.allocateNative(C_POINTER, scope);
// some_type** val_ptr_as_ma; (as a bare MemoryAddress)
MemoryAddress val_ptr_as_ma = val.address();
// some_type* val; (dereference/copy val, `*val_ptr`)
MemoryAddress val = MemoryAccess.getAddress(val);

请注意,在这种情况下我们必须通过 MemorySegment 路线。由于无法获取 MemoryAddress.

的地址

一般来说,Java API 没有与 & 运算符等效的运算符。 .address() 方法用于将 address-like 事物转换为 MemoryAddress 实例,而不是模仿 &。对于 MemoryAddress 本身,它只是 return this(因此您的 primary_image_handle.address() 调用无效)。

本质上,我们在 Java 中所做的 C 等价物,没有堆栈分配和 &,是这样的:

some_type** val_ptr = malloc(sizeof *val_ptr);
func(val_ptr); // void func(some_type** v) { ... }
some_type* val = *val_ptr;