// Code generated by gobind. DO NOT EDIT.

// Package main is an autogenerated binder stub for package interfaces.
//
//   autogenerated by gobind -lang=go interfaces
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
}
