Java 通过 JNI 调用 C / C++ / Golang
C / C++
先定义 Java native 接口:
package jni;
/**
* @author syf
* @date 2024/2/6
**/
public class JniMath {
static {
System.load("/tmp/libzichecpp.so");
System.load("/tmp/libzichego.so");
}
public static native long multiply(long x, long y);
public static native long multiplygo(long x, long y);
public static void main(String[] args) {
System.out.println(JniMath.multiply(12345, 67890));
System.out.println(JniMath.multiplygo(12345, 67890));
}
}
javah生成关联的头文件
javah jni.JniMath
生成的jni_JniMath.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_JniMath */
#ifndef _Included_jni_JniMath
#define _Included_jni_JniMath
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_JniMath
* Method: multiply
* Signature: (JJ)J
*/
JNIEXPORT jlong JNICALL Java_jni_JniMath_multiply
(JNIEnv *, jclass, jlong, jlong);
#ifdef __cplusplus
}
#endif
#endif
编写代码实现头文件中定义的函数:
#include "jni_JniMath.h"
JNIEXPORT jlong JNICALL Java_jni_JniMath_multiply
(JNIEnv * env, jclass clazz, jlong argX, jlong argY) {
return argX * argY;
}
编译 cpp,这里 JAVA_HOME 的头文件目录换成你的系统环境对应的
gcc -shared -fPIC -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin src/jni/jni_JniMath.c -o /tmp/libzichecpp.so
调用见 Java 部分的代码,不重复了
Golang
golang 从 1.5 版本开始支持 c-shared 模式编译,可以作为动态链接库调用
同样这里注释中cgo引入的CFLAG,头文件目录换成你的系统环境对应目录
package main
// #cgo CFLAGS: -I/Users/syf/opt/zulu-jdk-8/include
// #cgo CFLAGS: -I/Users/syf/opt/zulu-jdk-8/include/darwin
// #include <jni.h>
import "C"
//export Java_jni_JniMath_multiplygo
func Java_jni_JniMath_multiplygo(env *C.JNIEnv, clazz C.jclass, x C.jlong, y C.jlong) C.jlong {
return x * y
}
// main function is required, don't know why!
func main() {} // a dummy function
编译:
go build -buildmode=c-shared -o /tmp/libzichego.so src/jni/jni_math.go
调用见 Java 部分的代码,不重复了