我正在使用golang C
lib在Golang中实现Java Native Interface函数。
现在,我想使用JNI函数jstring
将GetStringUTFChars
转换为UTF-8字符串,但是这样做时出现错误。这些是我已经完成的步骤:
在我定义了JNI方法的Java类(称为MyClass)中,我有:
public static native void print(String msg);
我使用javah
用C语言定义的函数生成了.h
文件:
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变量。
答案 0 :(得分:1)
像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文件是因为文档中的以下子句:
在文件中使用// export会对序言进行限制:由于将其复制到两个不同的C输出文件中,因此它不得包含任何定义,而只能包含声明。