纯Java代码调用C函数
CLinker
CLinker是个类,来自Java新提案 JEP 412,连同MemoryHandles, MemoryAccess等用来简化JNI调用C函数的过程。它能做到无需JNI,直接通过纯Java代码调用C函数。
实现scanf和printf
测试类
import com.jmc.lang.time.Time;
import jdk.incubator.foreign.*;
import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.function.Consumer;
/**
* 测试CLinker <br>
* Compile Args: --add-modules jdk.incubator.foreign <br>
* VM (Runtime) Args: --enable-native-access=ALL-UNNAMED --add-modules jdk.incubator.foreign
*/
public class CLinkerTest {
public static void main(String[] args) throws Throwable {
// scanf & printf
var aPtr = Pointer.of(0);
var bPtr = Pointer.of(0L);
int res = scanf("%d %lld", aPtr, bPtr);
printf("scanf: a = %d, b = %lld, return value = %d.\n", aPtr.get(), bPtr.get(), res);
printf("---------------------------------------------\n");
printf("%s %s!\n", "Hello", "World");
printf("%d / %.1f = %.6lf\n", 10, 3.0f, 10 / 3.0);
printf("The time is: %s\n", Time.now());
}
public static int printf(String format, Object... args) {
var cLinker = CLinker.getInstance();
var lookup = CLinker.systemLookup();
var printf = cLinker.downcallHandle(
// vprintf才能传入va_list
lookup.lookup("vprintf").orElse(null),
MethodType.methodType(int.class, MemoryAddress.class