How to describe nested struct layout through jdk 22 ffm APIs?

Based on the example like [1]. I am able to access C compatible function. With following code, I am also able to access my custom Rust lib.
// JVM side
MethodHandle addNumbers = {
Linker linker = Linker.nativeLinker();
SymbolLookup rustlib = SymbolLookup.libraryLookup(
"target/release/libmylib.so",
Arena.global()
);
return linker.downcallHandle(
rustlib.find("add_numbers").orElseThrow(),
FunctionDescriptor.of(
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
)
);
}
Object result = addNumbers.invokeExact(10, 20)
System.out.println("Result:" + result)

// Rust side
#[no_mangle]
pub extern "C" fn add_numbers(x: i32, y: i32) -> i32 {
x + y
}
// JVM side
MethodHandle addNumbers = {
Linker linker = Linker.nativeLinker();
SymbolLookup rustlib = SymbolLookup.libraryLookup(
"target/release/libmylib.so",
Arena.global()
);
return linker.downcallHandle(
rustlib.find("add_numbers").orElseThrow(),
FunctionDescriptor.of(
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
)
);
}
Object result = addNumbers.invokeExact(10, 20)
System.out.println("Result:" + result)

// Rust side
#[no_mangle]
pub extern "C" fn add_numbers(x: i32, y: i32) -> i32 {
x + y
}
However, I have a problem describing complicated nested struct type. For instance, I have a custom struct MyStruct, which embeds a rustc_hash.FxHashMap, which in turns embeds a hashbrown.HashMap, which again contains 2 fields - one generic type S (a DefaultHashBuilder), and a RawTable, which contains a non public struct TableInner. In this case, 1. should I construct RawTable and all corresponded data struct such as TableInner, and so on before creating my custom structLayout i.e. MyStruct? 2. if yes, how to create structLayout that represents generic type e.g. S? Many thanks.
[1]. https://belief-driven-design.com/looking-at-java-22-foreign-function-memory-api-57fde/
6 Replies
JavaBot
JavaBot6d ago
This post has been reserved for your question.
Hey @everymen! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
stechy1
stechy16d ago
Hello, Recently I played a bit with the Java FFM API and I could just recommend you to try the "jextract" tool. It should generate a mapping from the provided header file to Java classes. So you don't have to write this cumbersome code by hand. https://github.com/openjdk/jextract/blob/master/doc/GUIDE.md
GitHub
jextract/doc/GUIDE.md at master · openjdk/jextract
https://openjdk.org/projects/code-tools. Contribute to openjdk/jextract development by creating an account on GitHub.
dan1st
dan1st6d ago
I'd say use jextract as suggested by stechy1 or change the native code so the function you are calling doesn't accept a hashmap. Instead, create a new native function that accepts an array of entries and call that from Java. You can also do that and use jextract If you want to use jextract, you probably need C header files for the generic type, you'd need to show how that specific generic type would be represented in C. I assume it's just whatever you want to pass directly embedded there (possibly as a pointer)
everymen
everymenOP6d ago
Ok. I will look into 1.) jextract, and 2.) test if I can create a wrapper that accepts a simpler data type, rather than hash map. Thank you for the advice!
JavaBot
JavaBot6d ago
If you are finished with your post, please close it. If you are not, please ignore this message. Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
JavaBot
JavaBot6d ago
Post Closed
This post has been closed by <@1225316541067825183>.

Did you find this page helpful?