Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert C.jstring to native string in Go

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)
       }
   }()
   // ???
}
like image 963
jarradhope Avatar asked Jul 28 '14 13:07

jarradhope


1 Answers

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.

like image 154
syntaqx Avatar answered Oct 18 '22 14:10

syntaqx