FFM API: questions about reinterpret and MemorySegment

Anastasiya Lisitskaya lisnas at gmail.com
Tue Oct 1 19:40:49 UTC 2024


Hi,

I'm trying to use the FFM API (jdk 22) to call my C++ method and I need to
pass a text (java String) and receive a text response. While implementing
this, I encountered several issues:

   1.

   What are the best practices for defining newSize for use in the
reinterpret(long
   newSize) method? Can I use constants like Long.MAX_VALUE or
   Integer.MAX_VALUE as newSize, or could that cause some problems?
   2.

   When I tried to use in-heap MemorySegment with the
   Linker.Option.critical(true)  and passed
   MemorySegment.ofArray(text.getBytes()), I started getting extra symbol
   like SOH in the response. What am I doing wrong? (Sample snippets listed
   below). Changing newSize value in reinterpret(long newSize) doesn't help
   3. If I inline MemorySegment.ofArray(text.getBytes()) into invokeExact,
   I expected : "мое все 123 аи92", but got:

>    uncaught exception:
>        address -> 0x60000120d710
>        what() -> "util/charset/wide.h:366: failed to decode UTF-8 string
>    at pos 25 in string "\xD0\x9C\xD0\xBE\xD1\x91 \xD0\xB2\xD1\x81\xD1\x91 123
>    \xD0\x90\xD0\23092\1\xCF\xFD\xBD_""
>        type -> yexception


I'm definitely doing something wrong. Please help me figure it out and
understand. Thanks!

Code snippets:
C++ method:

char* NormalizeText(const char* text, const char* lang);

Java code:

private static class FFNormalizerSettings {
>     private static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup();
>     public static final MemorySegment ADDR = SYMBOL_LOOKUP.find("NormalizeText").orElseThrow();
>     private static final FunctionDescriptor FUNCTION_DESCRIPTOR = FunctionDescriptor.of(
>             ValueLayout.ADDRESS,   // Return type
>             ValueLayout.ADDRESS,   // const char* text
>             ValueLayout.ADDRESS    // const char* lang
>     );
>     public static final MethodHandle HANDLE_CRITICAL;
>
>     static {
>         Linker linker = Linker.nativeLinker();
>         HANDLE_CRITICAL = linker.downcallHandle(ADDR, FUNCTION_DESCRIPTOR, Linker.Option.critical(true));
>     }
> }
>
>
method
*all OK:*

 public static String normalizeFFOfAddress(String text, Lang lang)
throws Throwable {
        String langCode = lang.getCode();
        try (Arena arena = Arena.ofConfined()) {
            *MemorySegment textSegment =
arena.allocateFrom(ValueLayout.JAVA_BYTE, text.getBytes());*
            MemorySegment langSegment = arena.allocateFrom(langCode);
            MemorySegment segment = (MemorySegment)
FFNormalizerSettings.HANDLE_CRITICAL.invokeExact(*textSegment*,
                    langSegment);
            MemorySegment reinterpret = segment.reinterpret(Long.MAX_VALUE);
            return reinterpret.getString(0);
        }
    }

Same method with MemorySegment textSegment = arena.allocateFrom(text);  - *all
OK*

*extra symbol SOH - NOT OK *(expected: "мое все 123 аи92" actual: "мое все
123 аи92A"):

 public static String normalizeFFOfAddress(String text, Lang lang)
throws Throwable {
        String langCode = lang.getCode();        *MemorySegment
textSegment = MemorySegment.ofArray(text.getBytes());*

       try (Arena arena = Arena.ofConfined()) {
            MemorySegment langSegment = arena.allocateFrom(langCode);
            MemorySegment segment = (MemorySegment)
FFNormalizerSettings.HANDLE_CRITICAL.invokeExact(*textSegment*,
                    langSegment);
            MemorySegment reinterpret = segment.reinterpret(Long.MAX_VALUE);
            return reinterpret.getString(0);
        }
    }

*uncaught exception - NOT OK* (expected: "мое все 123 аи92" actual:
exception):

 public static String normalizeFFOfAddress(String text, Lang lang)
throws Throwable {
        String langCode = lang.getCode();
        try (Arena arena = Arena.ofConfined()) {
            MemorySegment langSegment = arena.allocateFrom(langCode);
            MemorySegment segment = (MemorySegment)
FFNormalizerSettings.HANDLE_CRITICAL.invokeExact(*MemorySegment.ofArray(text.getBytes())*,
                    langSegment);
            MemorySegment reinterpret = segment.reinterpret(Long.MAX_VALUE);
            return reinterpret.getString(0);
        }
    }

uncaught exception:
    address -> 0x60000120d710
    what() -> "util/charset/wide.h:366: failed to decode UTF-8 string
at pos 25 in string "\xD0\x9C\xD0\xBE\xD1\x91 \xD0\xB2\xD1\x81\xD1\x91
123 \xD0\x90\xD0\23092\1\xCF\xFD\xBD_""
    type -> yexception

Thanks!

-- 
Lisitskaya Anastasiya
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20241001/2077806e/attachment.htm>


More information about the panama-dev mailing list