Java 16, como parte del paquete de incubación jdk.incubator.foreign , solía proporcionar una manera conveniente de convertir Java String s a cadenas C de Charset arbitrario usando MemorySegment CLingker.toCString(String str, Charset charset, NativeScope scope) . Ese método se eliminó desde Java 17. ¿Existe actualmente un método conveniente para convertir Java String a C string de Charset seleccionado?
Java 18 tiene void MemorySegment.setUtf8String(long offset, String str) . Sin embargo, eso obviamente solo es compatible con UTF8.
Uso este fragmento para convertir cadenas a UTF-16:
private static MemoryAddress string(String s, ResourceScope scope) { if (s == null) { return MemoryAddress.NULL; } byte[] data = s.getBytes(StandardCharsets.UTF_16LE); MemorySegment seg = MemorySegment.allocateNative(data.length + 2, scope); seg.copyFrom(MemorySegment.ofArray(data)); return seg.address(); } Tenga en cuenta que el carácter nulo final ocupa 2 bytes en UTF-16; si usa una codificación diferente, es posible que deba modificar la cadena antes ( s + '\000' ).
UTF-16 es lo suficientemente bueno para mis propósitos: llamar a la API de Windows.
En JDK18 utilizo una conversión de (s+"\0") que normalmente agrega 1, 2 o 4 bytes como terminación nula al final del segmento de MemorySegment para la cadena C, según el conjunto de caracteres utilizado:
static MemorySegment toCString(SegmentAllocator allocator, String s, Charset charset) { // "==" is OK here as StandardCharsets.UTF_8 == Charset.forName("UTF8") if (StandardCharsets.UTF_8 == charset) return allocator.allocateUtf8String(s); return allocator.allocateArray(ValueLayout.JAVA_BYTE, (s+"\0").getBytes(charset)); } Windows Java -> La cadena ancha es entonces: toCString(allocator, s, StandardCharsets.UTF_16LE)
Con suerte, alguien puede ofrecer una forma más eficiente / robusta de convertir. Lo anterior funciona para las pruebas de ida y vuelta que he realizado en un pequeño grupo de conjuntos de caracteres (Windows + WSL), pero no estoy seguro de que sea confiable en todas las situaciones.