// Package main is an autogenerated binder stub for package interfaces.
//   gobind -lang=go interfaces
//
// File is generated by gobind. Do not edit.
package main

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

*/
import "C"

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

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

//export proxyinterfaces_Error_Err
func proxyinterfaces_Error_Err(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.Error)
	res_0 := v.Err()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}

type proxyinterfaces_Error _seq.Ref

func (p *proxyinterfaces_Error) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_Error) Err() error {
	res := C.cproxyinterfaces_Error_Err(C.int32_t(p.Bind_proxy_refnum__()))
	var _res error
	_res_ref := _seq.FromRefNum(int32(res))
	if _res_ref != nil {
		if res < 0 { // go object
			_res = _res_ref.Get().(error)
		} else { // foreign object
			_res = (*proxy_error)(_res_ref)
		}
	}
	return _res
}

//export proxyinterfaces_I_Rand
func proxyinterfaces_I_Rand(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.I)
	res_0 := v.Rand()
	_res_0 := C.int32_t(res_0)
	return _res_0
}

type proxyinterfaces_I _seq.Ref

func (p *proxyinterfaces_I) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_I) Rand() int32 {
	res := C.cproxyinterfaces_I_Rand(C.int32_t(p.Bind_proxy_refnum__()))
	_res := int32(res)
	return _res
}

//export proxyinterfaces_I1_J
func proxyinterfaces_I1_J(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.I1)
	v.J()
}

//export proxyinterfaces_I2_G
func proxyinterfaces_I2_G(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.I2)
	v.G()
}

//export proxyinterfaces_I3_F
func proxyinterfaces_I3_F(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.I3)
	res_0 := v.F()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}

type proxyinterfaces_I3 _seq.Ref

func (p *proxyinterfaces_I3) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_I3) F() interfaces.I1 {
	res := C.cproxyinterfaces_I3_F(C.int32_t(p.Bind_proxy_refnum__()))
	var _res interfaces.I1
	_res_ref := _seq.FromRefNum(int32(res))
	if _res_ref != nil {
		if res < 0 { // go object
			_res = _res_ref.Get().(interfaces.I1)
		}
	}
	return _res
}

//export proxyinterfaces_Interfaces_SomeMethod
func proxyinterfaces_Interfaces_SomeMethod(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.Interfaces)
	v.SomeMethod()
}

type proxyinterfaces_Interfaces _seq.Ref

func (p *proxyinterfaces_Interfaces) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_Interfaces) SomeMethod() {
	C.cproxyinterfaces_Interfaces_SomeMethod(C.int32_t(p.Bind_proxy_refnum__()))
}

//export proxyinterfaces_LargerI_AnotherFunc
func proxyinterfaces_LargerI_AnotherFunc(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.LargerI)
	v.AnotherFunc()
}

//export proxyinterfaces_LargerI_Rand
func proxyinterfaces_LargerI_Rand(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.LargerI)
	res_0 := v.Rand()
	_res_0 := C.int32_t(res_0)
	return _res_0
}

type proxyinterfaces_LargerI _seq.Ref

func (p *proxyinterfaces_LargerI) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_LargerI) AnotherFunc() {
	C.cproxyinterfaces_LargerI_AnotherFunc(C.int32_t(p.Bind_proxy_refnum__()))
}

func (p *proxyinterfaces_LargerI) Rand() int32 {
	res := C.cproxyinterfaces_LargerI_Rand(C.int32_t(p.Bind_proxy_refnum__()))
	_res := int32(res)
	return _res
}

//export proxyinterfaces_SameI_Rand
func proxyinterfaces_SameI_Rand(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.SameI)
	res_0 := v.Rand()
	_res_0 := C.int32_t(res_0)
	return _res_0
}

type proxyinterfaces_SameI _seq.Ref

func (p *proxyinterfaces_SameI) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_SameI) Rand() int32 {
	res := C.cproxyinterfaces_SameI_Rand(C.int32_t(p.Bind_proxy_refnum__()))
	_res := int32(res)
	return _res
}

//export proxyinterfaces_WithParam_HasParam
func proxyinterfaces_WithParam_HasParam(refnum C.int32_t, param_p0 C.char) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(interfaces.WithParam)
	_param_p0 := param_p0 != 0
	v.HasParam(_param_p0)
}

type proxyinterfaces_WithParam _seq.Ref

func (p *proxyinterfaces_WithParam) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxyinterfaces_WithParam) HasParam(param_p0 bool) {
	var _param_p0 C.char = 0
	if param_p0 {
		_param_p0 = 1
	}
	C.cproxyinterfaces_WithParam_HasParam(C.int32_t(p.Bind_proxy_refnum__()), _param_p0)
}

//export proxyinterfaces__Add3
func proxyinterfaces__Add3(param_r C.int32_t) C.int32_t {
	var _param_r interfaces.I
	_param_r_ref := _seq.FromRefNum(int32(param_r))
	if _param_r_ref != nil {
		if param_r < 0 { // go object
			_param_r = _param_r_ref.Get().(interfaces.I)
		} else { // foreign object
			_param_r = (*proxyinterfaces_I)(_param_r_ref)
		}
	}
	res_0 := interfaces.Add3(_param_r)
	_res_0 := C.int32_t(res_0)
	return _res_0
}

//export proxyinterfaces__CallErr
func proxyinterfaces__CallErr(param_e C.int32_t) C.int32_t {
	var _param_e interfaces.Error
	_param_e_ref := _seq.FromRefNum(int32(param_e))
	if _param_e_ref != nil {
		if param_e < 0 { // go object
			_param_e = _param_e_ref.Get().(interfaces.Error)
		} else { // foreign object
			_param_e = (*proxyinterfaces_Error)(_param_e_ref)
		}
	}
	res_0 := interfaces.CallErr(_param_e)
	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 proxyinterfaces__Seven
func proxyinterfaces__Seven() C.int32_t {
	res_0 := interfaces.Seven()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}
