This is the sample code that im trying to run, both SDL.h and SDL_Vulkan.h extracted with JExtract The problem im having is getting the pNames which is declared as char**, my understanding of java FFI is that anything that start with * or ** and so on is a ValueLayout.ADDRESS, in this case a array of strings in pointer, so to acess it i would have to first get the ADDRESS of each char array in a loop and transform it in an another ValueLayout.ADDRESS and then use getUtf8String, the problem is im getting outOfBoundException when i try to access the values in the pointer inside the loop and im out of ideas on how to access those strings
public class Test {
public static void main(String[] args) throws NoSuchAlgorithmException {
try (var arena = Arena.openConfined()) {
if (SDL_Init(SDL_INIT_VIDEO()) < 0) {
System.out.println(SDL_GetError().getUtf8String(0));
} else {
var window = SDL_CreateWindow(arena.allocateUtf8String("Windows"), SDL_WINDOWPOS_UNDEFINED(),
SDL_WINDOWPOS_UNDEFINED(), 800, 600, SDL_WINDOW_VULKAN() | SDL_WINDOW_HIDDEN());
//unsigned int *pCount
var pCount = arena.allocate(ValueLayout.ADDRESS);
var bool = SDL_Vulkan_GetInstanceExtensions(window, pCount, NULL());
System.out.println(SDL_GetError().getUtf8String(0));
//get int of count
int inte = pCount.get(ValueLayout.JAVA_INT, 0);
//char **
var pNames = arena.allocate(ValueLayout.ADDRESS);
var bool2 = SDL_Vulkan_GetInstanceExtensions(window, pCount, pNames);
System.out.println(SDL_GetError().getUtf8String(0));
System.out.println(inte);
for (int i = 0; i < inte; i++) {
// char* (an element in the array)
var suggestion = pNames.getAtIndex(LibSDL2.C_POINTER, i);
// read the string
String pnameVk = suggestion.getUtf8String(0);
System.out.println(pnameVk);
}
}
}
}
}
I`ve tried accessing pNames with offset on getUtf8String of 4 bytes but no success either
EDIT: added suggestion by Jorn Vernee, still getting error on the 2nd value, first one now shows
im getting outOfBoundException when i try to access the values in the pointer inside the loop
See the section on zero-length memory segments in the javadoc of MemorySegment
The suggestion
region of memory who's address you read from the array has an unknown size, so the size of the memory segment is conservatively set to zero. To access the contents of the memory region, you either have to create a new MemorySegment with an explicit size using MemorySegment::ofAddress
, or use an unbounded address layout (in Java 20) to read the address, which would give you an accessible segment in the first place.
Jextract should already generate an unbounded address layout for you, so in this case it should be possible to use:
var suggestion = pNames.getAtIndex(C_POINTER, i);
This will make the suggestion
segment have a size of Long.MAX_VALUE
, which would allow you to read a string from it.