Last active
January 27, 2021 15:31
-
-
Save mkarg/6473496b5abe3630d6c86fe6fa0ddc81 to your computer and use it in GitHub Desktop.
Foreign Linker API (JDK 16 Incubator)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Demonstration of the Foreign Linker API (JDK 16 Incubator) | |
* | |
* The following code shows a message box using Win32 API with caption and text taken from CLI arguments 0 and 1. | |
* | |
* Incubator Warning: To compile this code, write a module-info.java file containing `requires jdk.incubator.foreign`. | |
* | |
* Incubator Warning: To execute this code, use `--add-modules jdk.incubator.foreign -Dforeign.restricted=permit`. | |
*/ | |
package eu.headcrashing; | |
import static java.nio.charset.StandardCharsets.UTF_16LE; | |
import static jdk.incubator.foreign.CLinker.C_INT; | |
import static jdk.incubator.foreign.CLinker.C_POINTER; | |
import static jdk.incubator.foreign.MemoryAddress.NULL; | |
import java.lang.invoke.MethodType; | |
import jdk.incubator.foreign.LibraryLookup; | |
import jdk.incubator.foreign.FunctionDescriptor; | |
import jdk.incubator.foreign.CLinker; | |
import jdk.incubator.foreign.MemoryAddress; | |
public class Sandbox { | |
public static void main(String[] args) { | |
System.out.println(messageBox(args[0], args[1])); | |
} | |
private static int messageBox(String text, String caption) { | |
try { | |
var user32 = LibraryLookup.ofLibrary("user32"); | |
var messageBoxFunction = user32.lookup("MessageBoxW"); | |
var messageBoxLayout = FunctionDescriptor.of(C_INT, C_POINTER, C_POINTER, C_POINTER, C_INT); | |
var javaMethodType = MethodType.methodType(int.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, int.class); | |
var methodHandle = CLinker.getInstance().downcallHandle(messageBoxFunction.get(), javaMethodType, messageBoxLayout); | |
try (var str1 = CLinker.toCString(text, UTF_16LE); var str2 = CLinker.toCString(caption, UTF_16LE)) { | |
return (int) methodHandle.invokeExact(NULL, str1.address(), str2.address(), 0); | |
} | |
} catch (RuntimeException e) { | |
throw e; | |
} catch (Throwable t) { | |
throw new RuntimeException(t); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment