Skip to content

ClarkGuan/jni

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jni

方便集成 JNI 代码的 Go 库。

完整支持所有 JNI 功能函数:https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html

配合 https://github.com/ClarkGuan/gojni 使用,方便 Java 与 Go 代码通信。

安装

安装前准备:

使用举例

我们假设您已经安装 JDK、Go 以及 C 编译器,这里以 MacOS 平台为例:

  • 目录结构
.
└── src
    └── java
        └── com
            └── demo
                └── Main.java
  • 编写 Java 源代码
package com.demo;

public class Main {
    static {
        System.loadLibrary("hello");
    }

    public static void main(String[] args) {
        nativeHello();
        System.out.println(stringFromJNI());
    }

    private static native void nativeHello();

    private static native String stringFromJNI();
}
gojni src/java/com/demo/Main.java
  • 此时在目录中生成文件 libs.clibs.go,我们修改 libs.go 文件内容如下:
package main

//
// #include <stdlib.h>
// #include <stddef.h>
// #include <stdint.h>
import "C"
import (
	"fmt"

	"github.com/ClarkGuan/jni"
)

//export jniOnLoad
func jniOnLoad(vm uintptr) {
	fmt.Println("JNI_OnLoad")
}

//export jniOnUnload
func jniOnUnload(vm uintptr) {
	fmt.Println("JNI_OnUnload")
}

//export jni_com_demo_nativeHello1
func jni_com_demo_nativeHello1(env uintptr, clazz uintptr) {
	fmt.Println("native hello form golang")
}

//export jni_com_demo_stringFromJNI2
func jni_com_demo_stringFromJNI2(env uintptr, clazz uintptr) uintptr {
	return jni.Env(env).NewString("This is string from Golang code!!!")
}

运行下面命令

go get github.com/ClarkGuan/jni@latest

将本 golang 库引入到 go.mod 文件中。

  • 运行 go build 生成 Mac 上运行的动态库文件:
go build -buildmode=c-shared -ldflags="-w -s" -v -x -o libhello.dylib

注意:需要将 JNI 的头文件引入,否则 C 编译器可能找不到。使用环境变量 CGO_CFLAGS:

CGO_CFLAGS="-I$JAVA_HOME/include -I$JAVA_HOME/include/darwin" go build -buildmode=c-shared -ldflags="-w -s" -v -x -o libhello.dylib

或者使用前面下载的 includejni 工具:

includejni go build -buildmode=c-shared -ldflags="-w -s" -v -x -o libhello.dylib

注意

includejni 工具只是帮您设置 CGO_CFLAGSCGO_CXXFLAGS 环境变量。如果您可以定义 localhost 的 JDK 头文件位置,则完全不需要此工具。

  • 编译 Java 源码
javac src/java/com/demo/Main.java
  • libhello.dylib 放入 Java 虚拟机可以找到的位置(通过 Java 环境变量 java.library.path 指定)

  • 运行 Java 程序

java -cp src com.demo.Main
  • 运行结果
JNI_OnLoad
native hello form golang
This is string from Golang code!!!