Skip to content

Instantly share code, notes, and snippets.

@xlab
Created July 11, 2015 16:29
Show Gist options
  • Save xlab/e35ab97dc318bc765f5b to your computer and use it in GitHub Desktop.
Save xlab/e35ab97dc318bc765f5b to your computer and use it in GitHub Desktop.
CGO helpers
// Glow automatically generated OpenGL binding: http://github.com/go-gl/glow
package gl
import (
"C"
"fmt"
"log"
"reflect"
"strings"
"unsafe"
)
// Ptr takes a pointer, slice, or array and returns its GL-compatible address.
func Ptr(data interface{}) unsafe.Pointer {
if data == nil {
return unsafe.Pointer(nil)
}
var addr unsafe.Pointer
v := reflect.ValueOf(data)
switch v.Type().Kind() {
case reflect.Ptr:
e := v.Elem()
switch e.Kind() {
case
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
addr = unsafe.Pointer(e.UnsafeAddr())
}
case reflect.Uintptr:
addr = unsafe.Pointer(v.Pointer())
case reflect.Slice:
addr = unsafe.Pointer(v.Index(0).UnsafeAddr())
case reflect.Array:
addr = unsafe.Pointer(v.UnsafeAddr())
default:
panic(fmt.Sprintf("Unsupported type %s; must be a pointer, slice, or array", v.Type()))
}
return addr
}
// PtrOffset takes a pointer offset and returns a GL-compatible pointer.
// Useful for functions such as glVertexAttribPointer that take pointer
// parameters indicating an offset rather than an absolute memory address.
func PtrOffset(offset int) unsafe.Pointer {
return unsafe.Pointer(uintptr(offset))
}
// Str takes a null-terminated Go string and returns its GL-compatible address.
// This function reaches into Go string storage in an unsafe way so the caller
// must ensure the string is not garbage collected.
func Str(str string) *int8 {
if !strings.HasSuffix(str, "\x00") {
log.Fatal("str argument missing null terminator", str)
}
header := (*reflect.StringHeader)(unsafe.Pointer(&str))
return (*int8)(unsafe.Pointer(header.Data))
}
// GoStr takes a null-terminated string returned by OpenGL and constructs a
// corresponding Go string.
func GoStr(cstr *uint8) string {
return C.GoString((*C.char)(unsafe.Pointer(cstr)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment