// Code generated by gobind. DO NOT EDIT.

// JNI functions for the Go <=> Java bridge.
//
//   autogenerated by gobind -lang=java vars

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

jclass proxy_class_vars_I;
jmethodID proxy_class_vars_I_cons;
jclass proxy_class_vars_S;
jmethodID proxy_class_vars_S_cons;

JNIEXPORT void JNICALL
Java_vars_Vars__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "vars/S");
    proxy_class_vars_S = (*env)->NewGlobalRef(env, clazz);
    proxy_class_vars_S_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "vars/Vars$proxyI");
    proxy_class_vars_I = (*env)->NewGlobalRef(env, clazz);
    proxy_class_vars_I_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "vars/I");
    
}

JNIEXPORT jint JNICALL
Java_vars_S__1_1New(JNIEnv *env, jclass clazz) {
    return new_vars_S();
}

JNIEXPORT void JNICALL
Java_vars_Vars_setABool(JNIEnv *env, jclass clazz, jboolean v) {
    char _v = (char)v;
    var_setvars_ABool(_v);
}

JNIEXPORT jboolean JNICALL
Java_vars_Vars_getABool(JNIEnv *env, jclass clazz) {
    char r0 = var_getvars_ABool();
    jboolean _r0 = r0 ? JNI_TRUE : JNI_FALSE;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAFloat(JNIEnv *env, jclass clazz, jdouble v) {
    double _v = (double)v;
    var_setvars_AFloat(_v);
}

JNIEXPORT jdouble JNICALL
Java_vars_Vars_getAFloat(JNIEnv *env, jclass clazz) {
    double r0 = var_getvars_AFloat();
    jdouble _r0 = (jdouble)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAFloat32(JNIEnv *env, jclass clazz, jfloat v) {
    float _v = (float)v;
    var_setvars_AFloat32(_v);
}

JNIEXPORT jfloat JNICALL
Java_vars_Vars_getAFloat32(JNIEnv *env, jclass clazz) {
    float r0 = var_getvars_AFloat32();
    jfloat _r0 = (jfloat)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAFloat64(JNIEnv *env, jclass clazz, jdouble v) {
    double _v = (double)v;
    var_setvars_AFloat64(_v);
}

JNIEXPORT jdouble JNICALL
Java_vars_Vars_getAFloat64(JNIEnv *env, jclass clazz) {
    double r0 = var_getvars_AFloat64();
    jdouble _r0 = (jdouble)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAString(JNIEnv *env, jclass clazz, jstring v) {
    nstring _v = go_seq_from_java_string(env, v);
    var_setvars_AString(_v);
}

JNIEXPORT jstring JNICALL
Java_vars_Vars_getAString(JNIEnv *env, jclass clazz) {
    nstring r0 = var_getvars_AString();
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAStructPtr(JNIEnv *env, jclass clazz, jobject v) {
    int32_t _v = go_seq_to_refnum(env, v);
    var_setvars_AStructPtr(_v);
}

JNIEXPORT jobject JNICALL
Java_vars_Vars_getAStructPtr(JNIEnv *env, jclass clazz) {
    int32_t r0 = var_getvars_AStructPtr();
    jobject _r0 = go_seq_from_refnum(env, r0, proxy_class_vars_S, proxy_class_vars_S_cons);
    return _r0;
}

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

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

JNIEXPORT void JNICALL
Java_vars_Vars_setAnInt16(JNIEnv *env, jclass clazz, jshort v) {
    int16_t _v = (int16_t)v;
    var_setvars_AnInt16(_v);
}

JNIEXPORT jshort JNICALL
Java_vars_Vars_getAnInt16(JNIEnv *env, jclass clazz) {
    int16_t r0 = var_getvars_AnInt16();
    jshort _r0 = (jshort)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAnInt32(JNIEnv *env, jclass clazz, jint v) {
    int32_t _v = (int32_t)v;
    var_setvars_AnInt32(_v);
}

JNIEXPORT jint JNICALL
Java_vars_Vars_getAnInt32(JNIEnv *env, jclass clazz) {
    int32_t r0 = var_getvars_AnInt32();
    jint _r0 = (jint)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAnInt64(JNIEnv *env, jclass clazz, jlong v) {
    int64_t _v = (int64_t)v;
    var_setvars_AnInt64(_v);
}

JNIEXPORT jlong JNICALL
Java_vars_Vars_getAnInt64(JNIEnv *env, jclass clazz) {
    int64_t r0 = var_getvars_AnInt64();
    jlong _r0 = (jlong)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAnInt8(JNIEnv *env, jclass clazz, jbyte v) {
    int8_t _v = (int8_t)v;
    var_setvars_AnInt8(_v);
}

JNIEXPORT jbyte JNICALL
Java_vars_Vars_getAnInt8(JNIEnv *env, jclass clazz) {
    int8_t r0 = var_getvars_AnInt8();
    jbyte _r0 = (jbyte)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_vars_Vars_setAnInterface(JNIEnv *env, jclass clazz, jobject v) {
    int32_t _v = go_seq_to_refnum(env, v);
    var_setvars_AnInterface(_v);
}

JNIEXPORT jobject JNICALL
Java_vars_Vars_getAnInterface(JNIEnv *env, jclass clazz) {
    int32_t r0 = var_getvars_AnInterface();
    jobject _r0 = go_seq_from_refnum(env, r0, proxy_class_vars_I, proxy_class_vars_I_cons);
    return _r0;
}

