// Code generated by gobind. DO NOT EDIT.

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

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

jclass proxy_class_aliases_S;
jmethodID proxy_class_aliases_S_cons;

JNIEXPORT void JNICALL
Java_aliases_Aliases__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "aliases/S");
    proxy_class_aliases_S = (*env)->NewGlobalRef(env, clazz);
    proxy_class_aliases_S_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
}

JNIEXPORT void JNICALL
Java_aliases_Aliases_takesAByte(JNIEnv* env, jclass _clazz, jbyte a) {
    uint8_t _a = (uint8_t)a;
    proxyaliases__TakesAByte(_a);
}

JNIEXPORT void JNICALL
Java_aliases_Aliases_takesAByteSlice(JNIEnv* env, jclass _clazz, jbyteArray a) {
    nbyteslice _a = go_seq_from_java_bytearray(env, a, 0);
    proxyaliases__TakesAByteSlice(_a);
    go_seq_release_byte_array(env, a, _a.ptr);
}

JNIEXPORT void JNICALL
Java_aliases_Aliases_takesAByteSliceAlias(JNIEnv* env, jclass _clazz, jbyteArray a) {
    nbyteslice _a = go_seq_from_java_bytearray(env, a, 0);
    proxyaliases__TakesAByteSliceAlias(_a);
    go_seq_release_byte_array(env, a, _a.ptr);
}

JNIEXPORT void JNICALL
Java_aliases_Aliases_takesAStructPtr(JNIEnv* env, jclass _clazz, jobject a) {
    int32_t _a = go_seq_to_refnum(env, a);
    proxyaliases__TakesAStructPtr(_a);
}

JNIEXPORT void JNICALL
Java_aliases_Aliases_takesAStructPtrAlias(JNIEnv* env, jclass _clazz, jobject a) {
    int32_t _a = go_seq_to_refnum(env, a);
    proxyaliases__TakesAStructPtrAlias(_a);
}

JNIEXPORT jint JNICALL
Java_aliases_S__1_1New(JNIEnv *env, jclass clazz) {
    return new_aliases_S();
}

