// Code generated by gobind. DO NOT EDIT.

// Package main is an autogenerated binder stub for package basictypes.
//
//   autogenerated by gobind -lang=go basictypes
package main

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "basictypes.h"

*/
import "C"

import (
	"basictypes"
	_seq "golang.org/x/mobile/bind/seq"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

//export proxybasictypes__Bool
func proxybasictypes__Bool(param_p0 C.char) C.char {
	_param_p0 := param_p0 != 0
	res_0 := basictypes.Bool(_param_p0)
	var _res_0 C.char = 0
	if res_0 {
		_res_0 = 1
	}
	return _res_0
}

//export proxybasictypes__ByteArrays
func proxybasictypes__ByteArrays(param_x C.nbyteslice) C.nbyteslice {
	_param_x := toSlice(param_x, false)
	res_0 := basictypes.ByteArrays(_param_x)
	_res_0 := fromSlice(res_0, true)
	return _res_0
}

//export proxybasictypes__Error
func proxybasictypes__Error() C.int32_t {
	res_0 := basictypes.Error()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}

//export proxybasictypes__ErrorPair
func proxybasictypes__ErrorPair() (C.nint, C.int32_t) {
	res_0, res_1 := basictypes.ErrorPair()
	_res_0 := C.nint(res_0)
	var _res_1 C.int32_t = _seq.NullRefNum
	if res_1 != nil {
		_res_1 = C.int32_t(_seq.ToRefNum(res_1))
	}
	return _res_0, _res_1
}

//export proxybasictypes__Ints
func proxybasictypes__Ints(param_x C.int8_t, param_y C.int16_t, param_z C.int32_t, param_t C.int64_t, param_u C.nint) {
	_param_x := int8(param_x)
	_param_y := int16(param_y)
	_param_z := int32(param_z)
	_param_t := int64(param_t)
	_param_u := int(param_u)
	basictypes.Ints(_param_x, _param_y, _param_z, _param_t, _param_u)
}
