Nice way to convert `*int` to `*C.int`?

Hi all,

I was wondering if there is a nice way to convert from *int to *C.int, that works across different architectures with different word sizes?

(*C.int)(&a) fails to compile (on a x86_64 system) while I feel (*C.int)(unsafe.Pointer(&a)) is dangerous. My current workaround involves using reflect:

var retVal int
var a C.int
size := reflect.TypeOf(a).Size()
switch size {
case 2:
    var tmp int16
    C.cgocall((*C.int)(&tmp))
    retVal = int(tmp)
case 4:
    var tmp int32
    C.cgocall((*C.int)(&tmp))
    retVal = int(tmp)
case 8:
    var tmp int64
    C.cgocall((*C.int)(&tmp))
    retVal = int(tmp)
}

Now, this is ugly as heck (and doesn’t compile). And it adds a lot of touch points to my code which I’m not the best at, and I’d really rather be familiar with my code.

Any help would be fantastic!

From https://golang.org/cmd/cgo/, you can get the size of any C type with C.sizeof_T replacing T with your type, in this case C.sizeof_int.

This will at least get rid of reflection to pick sizes.

I got something that seems to work. I only have an x86_64 to test it on and the int will be truncated or something, but it compiles and runs.

calls.h

void cgocall(int* i) {
	*i = 42;
}

main.go

package main

// #include "calls.h"
import "C"

import (
	"log"
	"reflect"
)

func main() {
	log.SetFlags(log.Lshortfile)

	var input int = 12
	log.Println(C.sizeof_int, reflect.TypeOf(input).Size())

	log.Println(input)

	tmp := C.int(input)
	C.cgocall((*C.int)(&tmp))
	input = int(tmp)

	log.Println(input)
}

output

main.go:15: 4 8
main.go:17: 12
main.go:23: 42

Notice the sizes of the integers are different, but the conversion still worked. Please make sure it works as you expect on the systems you need to run on. I think the values will be truncated, but that could still be bad.

Yeah, turns out there is no way to do pointer-to-pointer conversion without being unsafe. It will always need a conversion from int to C.int as they’re different types.

Oh well.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.