簡體   English   中英

如何從 Go 代碼調用 Java 本機接口 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 類(稱為 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 規范中定義的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 文件只用於包裝函數是因為文檔中的這個子句:

在文件中使用 //export 會對序言進行限制:因為它被復制到兩個不同的 C 輸出文件中,所以它不能包含任何定義,只能包含聲明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM