<div dir="auto">Thanks Maurizio for the clear explanation.<div dir="auto">Since last time I experimented with Panama the api changed a lot.<div dir="auto">I will need to look more into what jextract generates to understand the current api better. </div><div dir="auto"><br></div><div dir="auto">Great regards </div><div dir="auto">RedIODev </div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 22, 2024, 22:42 Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>
<div>
<p><br>
</p>
<div>On 22/01/2024 20:01, Red IO wrote:<br>
</div>
<blockquote type="cite">
<div dir="auto">I know that the original question is answered, but
how would you free memory in case the libraries documentation
says to use free. Would you just create a method handle to libc
free and call it with the pointer or is there an api to free
native memory?</div>
</blockquote>
<p>If the API says to use free, then you should have a downcall
method handle for "free" and call that (using the same technique
with MemorySegment::reinterpret I showed in the last email).</p>
<p>(Note: when using jextract, chances are that "free" will come
along for the ride in the extracted classes).<br>
</p>
<p>Maurizio<br>
</p>
<blockquote type="cite">
<div dir="auto">
<div dir="auto">Great regards </div>
<div dir="auto">RedIODev </div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Mon, Jan 22, 2024, 19:36
Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank" rel="noreferrer">maurizio.cimadamore@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi
tison,<br>
in this case, the function is returning a pointer. What
happens to that <br>
pointer is 100% library-dependent. In this case, doing `man
getpwnam` <br>
gives us some clues:<br>
<br>
> The return value may point to a static area, and may be
overwritten by<br>
> subsequent calls to getpwent(3), getpwnam(), or
getpwuid(). <br>
> (Do not<br>
> pass the returned pointer to free(3).)<br>
<br>
Basically, the returned pointer points to an area that is
managed by the <br>
library, so you don't have to free.<br>
<br>
This means the code you have seems correct to me.<br>
<br>
Other libraries will behave differently, for instance they
might have a <br>
pair of functions such as "createFoo" and "destroyFoo", the
former <br>
allocating region of memory, and the latter destroying such
region. In <br>
such cases it might be helpful to associate the return memory
segment to <br>
an existing arena *and* also attach a cleanup function (via <br>
MemorySegment::reinterpret), so that, when the arena is
closed, <br>
"destroyFoo" is called on the pointer.<br>
<br>
Hope this helps<br>
<br>
Maurizio<br>
<br>
<br>
On 22/01/2024 18:28, tison wrote:<br>
> Here is the code snippet:<br>
><br>
> public static void main(String[] args) throws
Throwable {<br>
> final Linker linker = Linker.nativeLinker();<br>
> final SymbolLookup libc =
linker.defaultLookup();<br>
> final MethodHandle handle =<br>
>
linker.downcallHandle(libc.find("getpwnam").orElseThrow(),<br>
> FunctionDescriptor.of(ValueLayout.ADDRESS,
ValueLayout.ADDRESS));<br>
> try (Arena arena = Arena.ofConfined()) {<br>
> final MemorySegment passwd = (MemorySegment)<br>
> handle.invoke(arena.allocateUtf8String("tison"));<br>
> System.out.println("passwd=" + passwd);<br>
> System.out.println("pw_name=" +<br>
>
passwd.reinterpret(Long.MAX_VALUE).get(ValueLayout.ADDRESS,<br>
> 48).reinterpret(Long.MAX_VALUE).getUtf8String(0));<br>
> }<br>
> }<br>
><br>
> I wonder if I should explicitly free passwd that is
returned from a<br>
> native method. If so, how? If not, how the Arena tracks
it and free on<br>
> closed?<br>
><br>
> Best,<br>
> tison.<br>
</blockquote>
</div>
</blockquote>
</div>
</blockquote></div>