猿问

如何从我的 Go 代码调用 Java 本机接口 C 函数?

我准备使用 golangC库在 Golang 中实现我的 Java 本机接口函数。

现在我想jstring使用 JNI 函数将 a 转换为 UTF-8 字符串GetStringUTFChars,但在执行此操作时出现错误。这些是我完成的步骤:


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


public static native void print(String msg);

使用,我用C 语言定义的函数javah生成了-file:.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 规范GetStringUTFChars中定义的,然后我可以打印字符串?fmt.println


编辑 2

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


阿晨1998
浏览 165回答 1
1回答

Smart猫小萌

JNI 函数GetStringUTFChars是函数指针,不能直接从 Go 调用。您必须将所需的函数包装在一个单独的 C 文件中。例如jx.c#include <jni.h>const char* jx_GetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy) {&nbsp; &nbsp; 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 (&nbsp; &nbsp; "fmt")//export Java_com_mypackage_MyClass_printfunc Java_com_mypackage_MyClass_print(env *C.JNIEnv, clazz C.jclass, str C.jstring) {&nbsp; &nbsp; s := C.jx_GetStringUTFChars(env, str, (*C.jboolean)(nil))&nbsp; &nbsp; fmt.Println(C.GoString(s))}func main() {}包装函数有一个单独的 C 文件的原因是因为文档中的这个子句:在文件中使用 //export 对前导码施加了限制:因为它被复制到两个不同的 C 输出文件中,所以它不能包含任何定义,只能包含声明。
随时随地看视频慕课网APP

相关分类

Go
我要回答