How can I convert a C.jstring to a usable string in Go?
I am using GoAndroid.
In C you can do something like in this stackoverflow thread
JNIEXPORT void JNICALL Java_ClassName_MethodName(JNIEnv *env, jobject obj, jstring javaString)
{
const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0);
// use your string
(*env)->ReleaseStringUTFChars(env, javaString, nativeString);
}
in Go it starts to look something like this
func Java_ClassName_MethodName(env *C.JNIEnv, clazz C.jclass, jstring javaString) {
defer func() {
if err := recover(); err != nil {
log.Fatalf("panic: init: %v\n", err)
}
}()
// ???
}
I know this question is old, but I recently ran into this and thought I'd elaborate a bit for anyone else that winds up here:
JNI functions like GetStringUTFChars
are function pointers that cannot be called directly from Go. You have to wrap the functions in a separate C file, e.g.:
jx.c
#include <jni.h> const char* jx_GetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy) { return (*env)->GetStringUTFChars(env, str, isCopy); }
After creating a library from the C file, your Go file will look something like this:
package main
/*
#cgo CFLAGS: -I/usr/java/jdkX.X.X_XXX/include/ -I/usr/java/jdkX.X.X_XXX/include/linux/
#cgo LDFLAGS: -L${SRCDIR}/ -ljx
#include "jx.h"
*/
import "C"
import (
"fmt"
)
//export Java_com_mypackage_MyClass_print
func Java_ClassName_MethodName(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() {}
The reason why there is a separate C file just for the wrapper function is because of this clause in the documentation:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With