如何从我的 Go 代码中调用 Java Native Interface C 函数?

How do I call a Java Native Interface C function from my Go code?

我打算使用 golang C 库在 Golang 中实现我的 Java 本机接口函数。
现在我想使用 JNI 函数 GetStringUTFCharsjstring 转换为 UTF-8 字符串,但在执行此操作时出现错误。这些是我完成的步骤:

在我定义 JNI 方法的 Java class(称为 MyClass)中,我有:

public static native void print(String msg);

使用 javah,我生成了 .h-文件,其中包含 C 语言定义的函数:

JNIEXPORT void JNICALL Java_com_mypackage_MyClass_print
  (JNIEnv *, jclass, jstring);

然后,在我的 Go 代码中有以下代码:

package main

// #cgo CFLAGS: -I/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/include
// #cgo CFLAGS: -I/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/include/darwin
/*
#include <jni.h>
*/
import "C"

//export Java_com_mypackage_MyClass_print
func Java_com_mypackage_MyClass_print(env *C.JNIEnv, clazz C.jclass, str C.jstring) {

    _ = C.GetStringUTFChars(env, str, 0)

}

当我构建 go 文件时使用:
go build -buildmode=c-shared -o libmyclass.dylib libmyclass.go
然后我得到以下错误:

could not determine kind of name for C.GetStringUTFChars

我应该如何调用 JNI spec 中定义的 GetStringUTFChars 以便我可以使用 fmt.println 打印字符串?

编辑 2
删除了 "edit 1" 因为上面的过程是正确的,只是没有设置 LD_LIBRARY_PATH 变量。

GetStringUTFChars这样的JNI函数是函数指针,不能直接从Go中调用。您必须将所需的函数包装在一个单独的 C 文件中。例如

jx.c

#include <jni.h>

const char* jx_GetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy) {
    return (*env)->GetStringUTFChars(env, str, isCopy);
}

从 C 文件创建库后,您的 Go 文件将如下所示:

package main

/*
#cgo CFLAGS: -I/usr/java/jdk1.8.0_162/include/ -I/usr/java/jdk1.8.0_162/include/linux/
#cgo LDFLAGS: -L${SRCDIR}/ -ljx

#include "jx.h"
*/
import "C"
import (
    "fmt"
)

//export Java_com_mypackage_MyClass_print
func Java_com_mypackage_MyClass_print(env *C.JNIEnv, clazz C.jclass, str C.jstring) {
    s := C.jx_GetStringUTFChars(env, str, (*C.jboolean)(nil))
    fmt.Println(C.GoString(s))
}

func main() {}

之所以有一个单独的 C 文件只是为了包装函数,是因为文档中的这个条款:

Using //export in a file places a restriction on the preamble: since it is copied into two different C output files, it must not contain any definitions, only declarations.