<div dir="ltr">For example, getpwnam returns passwd struct, but the struct layout is various on different platform, making the code snippet below unportable:<br><br>        final Linker linker = Linker.nativeLinker();<br>        final SymbolLookup lookup = linker.defaultLookup();<br>        final MemorySegment getpwnam = lookup.find("getpwnam").orElseThrow();<br>        final MethodHandle getpwnamFn = linker.downcallHandle(getpwnam, FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS));<br>        final StructLayout passwdLayout = MemoryLayout.structLayout(<br>                ValueLayout.ADDRESS.withName("pw_name"),<br>                ValueLayout.ADDRESS.withName("pw_passwd"),<br>                ValueLayout.JAVA_INT.withName("pw_uid"),<br>                ValueLayout.JAVA_INT.withName("pw_gid"),<br>                ValueLayout.JAVA_LONG.withName("pw_change"),<br>                ValueLayout.ADDRESS.withName("pw_class"),<br>                ValueLayout.ADDRESS.withName("pw_gecos"),<br>                ValueLayout.ADDRESS.withName("pw_dir"),<br>                ValueLayout.ADDRESS.withName("pw_shell"),<br>                ValueLayout.JAVA_LONG.withName("pw_expire"),<br>                ValueLayout.JAVA_INT.withName("pw_fields"));<br>        try (final Arena arena = Arena.ofConfined()) {<br>            final MemorySegment username = arena.allocateUtf8String(user);<br>            final MemorySegment passwd = ((MemorySegment) getpwnamFn.invoke(username)).reinterpret(Long.MAX_VALUE);<br>            final MemorySegment dir = passwd.get(<br>                    ValueLayout.ADDRESS,<br>                    passwdLayout.byteOffset(MemoryLayout.PathElement.groupElement("pw_dir")));<br>            System.out.println(dir.reinterpret(Long.MAX_VALUE).getUtf8String(0));<br>        }<div><br></div><div>This code snippet only works <span class="gmail_default" style="font-family:arial,sans-serif">on macOS because the layout differs on other platforms.</span></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif"><span class="gmail_default" style="font-family:arial,sans-serif">In Rust, we can use #[target(os = ..)] to switch the manner, and in Java, perhaps we can use inheritance or interfaces, but it still lacks:</span></font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif"><span class="gmail_default" style="font-family:arial,sans-serif">* A unified way to determine current os, arch, toolchain, etc. I made [1] that can help but it's no more than another incomplete slang.</span></font></div><div><font face="arial, sans-serif"><span class="gmail_default" style="font-family:arial,sans-serif">* A compile-time dispatch decision. Maybe with static initialization block it can helps by generating 'static final' MethodHandle/VarHandle. I don't know.</span><br></font><br>Best,<br>tison.</div><div><br></div><div><div class="gmail_default" style="font-family:arial,sans-serif">[1] <a href="http://github.com/tisonspieces/os-detector">github.com/tisonspieces/os-detector</a></div><br></div></div>