Varun
Varun

Reputation: 1043

casting to struct type in go lang

I have some c macros in the form of

#define VARATT_IS_4B(PTR) \
    ((((varattrib_1b *) (PTR))->va_header & 0x80) == 0x00)

and want to convert it to Go lang. I am doing something like

func varAttIs1B(ptr uintptr) bool {
    return (*varAttrib1b(ptr).vaHeader & 0x01) == 0x01
}

but yeah, it is not working and I am getting compiler error "cannot convert ptr (type int) to type varAttrib1b".

varAttrib1b is a struct with two fields and ptr is a uintptr(could be some other type also).

type varAttrib1b struct {
    vaHeader uint8
    vaData   []string
}

How can I do this?

Upvotes: 1

Views: 2142

Answers (1)

Soheil Hassas Yeganeh
Soheil Hassas Yeganeh

Reputation: 1379

You cannot cast pointers to arbitrary types in Go. If you really want to do that, you should use unsafe.Pointer:

type varAttrib1b struct {
    vaHeader uint8
    vaData   []string
}

func varAttIs1B(ptr uintptr) bool {
    return ((*varAttrib1b)(unsafe.Pointer(ptr)).vaHeader & 0x01) == 0x01
}

It compiles and works, but are you sure there is no safe way of doing that in go? Can't you just define an interface:

type Attr interface {
    AttrIs1B() bool
}

func (b varAttrib1b) AttrIs1B() bool {
    return b.vaHeader & 0x01 == 0x01
}

func varAttIs1B(attr Attr) bool {
    return attr.AttrIs1B()
}

Or implement it with type casts?

func varAttIs1B(ptr interface{}) bool {
    switch a := ptr.(type) {
    case varAttrib1b:
        return a.vaHeader & 0x01 == 0x01
    }
    return false
}

Upvotes: 4

Related Questions