// JNI functions for the Go <=> Java bridge.
//   gobind -lang=java underscores
//
// File is generated by gobind. Do not edit.

#include <android/log.h>
#include <stdint.h>
#include "seq.h"
#include "_cgo_export.h"
#include "underscore_pkg.h"

jclass proxy_class_underscore_pkg_Underscore_struct;
jmethodID proxy_class_underscore_pkg_Underscore_struct_cons;

JNIEXPORT void JNICALL
Java_underscore_1pkg_Underscore_1pkg__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "underscore_pkg/Underscore_struct");
    proxy_class_underscore_pkg_Underscore_struct = (*env)->NewGlobalRef(env, clazz);
    proxy_class_underscore_pkg_Underscore_struct_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
}

JNIEXPORT void JNICALL
Java_underscore_1pkg_Underscore_1pkg_underscore_1func(JNIEnv* env, jclass _clazz) {
    proxyunderscore_pkg__Underscore_func();
}

JNIEXPORT jint JNICALL
Java_underscore_1pkg_Underscore_1struct__1_1New(JNIEnv *env, jclass clazz) {
    return new_underscore_pkg_Underscore_struct();
}

JNIEXPORT void JNICALL
Java_underscore_1pkg_Underscore_1struct_setUnderscore_1field(JNIEnv *env, jobject this, jstring v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring _v = go_seq_from_java_string(env, v);
    proxyunderscore_pkg_Underscore_struct_Underscore_field_Set(o, _v);
}

JNIEXPORT jstring JNICALL
Java_underscore_1pkg_Underscore_1struct_getUnderscore_1field(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring r0 = proxyunderscore_pkg_Underscore_struct_Underscore_field_Get(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

JNIEXPORT void JNICALL
Java_underscore_1pkg_Underscore_1pkg_setUnderscore_1var(JNIEnv *env, jclass clazz, jlong v) {
    nint _v = (nint)v;
    var_setunderscore_pkg_Underscore_var(_v);
}

JNIEXPORT jlong JNICALL
Java_underscore_1pkg_Underscore_1pkg_getUnderscore_1var(JNIEnv *env, jclass clazz) {
    nint r0 = var_getunderscore_pkg_Underscore_var();
    jlong _r0 = (jlong)r0;
    return _r0;
}

