如何通过 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_handle
。 It 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 但原作者不想那样做。
你的代码对我来说几乎是正确的。您只需要保留分配的段(代表 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;
我想在 C 中调用以下方法(已定义 here):
heif_image_handle* handle;
heif_context_get_primary_image_handle(ctx, &handle);
我遇到的问题是我无法通过 C-API 访问结构 heif_image_handle
。 It 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 但原作者不想那样做。
你的代码对我来说几乎是正确的。您只需要保留分配的段(代表 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;