FAQ
nvm: as I was writing this I realized y should be uint64

I am having trouble with size_t pointers in cgo:

// void foo(int *x)
// void bar(size_t *y)

var x int32
var y int64

foo((*C.int)(&x)) // works
bar((*C.size_t)(&y)) // error: cannot convert &y (type *int64) to type
*_Ctype_size_t

This is on 64 bit linux with gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

Should y be of some other type?

--

Search Discussions

  • Minux at Nov 14, 2012 at 7:43 am

    On Wednesday, November 14, 2012, serbaut wrote:

    nvm: as I was writing this I realized y should be uint64

    I am having trouble with size_t pointers in cgo:

    // void foo(int *x)
    // void bar(size_t *y)

    var x int32
    var y int64

    foo((*C.int)(&x)) // works
    bar((*C.size_t)(&y)) // error: cannot convert &y (type *int64) to type
    *_Ctype_size_t

    This is on 64 bit linux with gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

    Should y be of some other type?
    i think it's better to use uintptr for c type size_t.

    also note that you need to first convert &y to unsafe.Pointer type
    and then convert that to *C.size_t. Go doesn't allow arbitrary
    conversion between pointer types, it must go through unsafe.Pointer.

    --
  • Serbaut at Nov 14, 2012 at 8:23 pm
    Not sure what you mean, the following runs fine with go tip:

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import "fmt"

    func main() {
    var x int32
    var y uint64
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(&y))
    fmt.Println(x, y)
    }
    On Wednesday, November 14, 2012 8:43:44 AM UTC+1, minux wrote:

    On Wednesday, November 14, 2012, serbaut wrote:

    nvm: as I was writing this I realized y should be uint64

    I am having trouble with size_t pointers in cgo:

    // void foo(int *x)
    // void bar(size_t *y)

    var x int32
    var y int64

    foo((*C.int)(&x)) // works
    bar((*C.size_t)(&y)) // error: cannot convert &y (type *int64) to type
    *_Ctype_size_t

    This is on 64 bit linux with gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

    Should y be of some other type?
    i think it's better to use uintptr for c type size_t.

    also note that you need to first convert &y to unsafe.Pointer type
    and then convert that to *C.size_t. Go doesn't allow arbitrary
    conversion between pointer types, it must go through unsafe.Pointer.
    --
  • Bryanturley at Nov 14, 2012 at 8:46 pm

    On Wednesday, November 14, 2012 2:23:00 PM UTC-6, serbaut wrote:
    Not sure what you mean, the following runs fine with go tip:

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import "fmt"

    func main() {
    var x int32
    var y uint64
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(&y))
    fmt.Println(x, y)
    }
    On Wednesday, November 14, 2012 8:43:44 AM UTC+1, minux wrote:

    On Wednesday, November 14, 2012, serbaut wrote:

    nvm: as I was writing this I realized y should be uint64

    I am having trouble with size_t pointers in cgo:

    // void foo(int *x)
    // void bar(size_t *y)

    var x int32
    var y int64

    foo((*C.int)(&x)) // works
    bar((*C.size_t)(&y)) // error: cannot convert &y (type *int64) to type
    *_Ctype_size_t

    This is on 64 bit linux with gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

    Should y be of some other type?
    i think it's better to use uintptr for c type size_t.

    also note that you need to first convert &y to unsafe.Pointer type
    and then convert that to *C.size_t. Go doesn't allow arbitrary
    conversion between pointer types, it must go through unsafe.Pointer.
    The problem is int is 32bit on 32bit platforms and will soon be 64bit on
    64bit platforms.
    uintptr also adjusts it's size based on target arch, which probably the
    reason size_t was created as well.

    --
  • Serbaut at Nov 14, 2012 at 9:04 pm
    How should I rewrite the code above in that case?
    On Wednesday, November 14, 2012 9:39:59 PM UTC+1, bryanturley wrote:
    On Wednesday, November 14, 2012 2:23:00 PM UTC-6, serbaut wrote:

    Not sure what you mean, the following runs fine with go tip:

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import "fmt"

    func main() {
    var x int32
    var y uint64
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(&y))
    fmt.Println(x, y)
    }
    On Wednesday, November 14, 2012 8:43:44 AM UTC+1, minux wrote:

    On Wednesday, November 14, 2012, serbaut wrote:

    nvm: as I was writing this I realized y should be uint64

    I am having trouble with size_t pointers in cgo:

    // void foo(int *x)
    // void bar(size_t *y)

    var x int32
    var y int64

    foo((*C.int)(&x)) // works
    bar((*C.size_t)(&y)) // error: cannot convert &y (type *int64) to type
    *_Ctype_size_t

    This is on 64 bit linux with gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

    Should y be of some other type?
    i think it's better to use uintptr for c type size_t.

    also note that you need to first convert &y to unsafe.Pointer type
    and then convert that to *C.size_t. Go doesn't allow arbitrary
    conversion between pointer types, it must go through unsafe.Pointer.
    The problem is int is 32bit on 32bit platforms and will soon be 64bit on
    64bit platforms.
    uintptr also adjusts it's size based on target arch, which probably the
    reason size_t was created as well.
    --
  • Uli Kunitz at Nov 15, 2012 at 6:40 am
    I would put that more precise: The language specification defines that uint
    and int might have 32 bit or 64 bit size whereby int and uint must have the
    same size.

    Actually the size of uint and int will change from 32 bit to 64 bit from
    1.0.3 to 1.1 on amd64.

    On Wednesday, November 14, 2012 9:39:59 PM UTC+1, bryanturley wrote:
    On Wednesday, November 14, 2012 2:23:00 PM UTC-6, serbaut wrote:

    Not sure what you mean, the following runs fine with go tip:

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import "fmt"

    func main() {
    var x int32
    var y uint64
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(&y))
    fmt.Println(x, y)
    }
    On Wednesday, November 14, 2012 8:43:44 AM UTC+1, minux wrote:

    On Wednesday, November 14, 2012, serbaut wrote:

    nvm: as I was writing this I realized y should be uint64

    I am having trouble with size_t pointers in cgo:

    // void foo(int *x)
    // void bar(size_t *y)

    var x int32
    var y int64

    foo((*C.int)(&x)) // works
    bar((*C.size_t)(&y)) // error: cannot convert &y (type *int64) to type
    *_Ctype_size_t

    This is on 64 bit linux with gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

    Should y be of some other type?
    i think it's better to use uintptr for c type size_t.

    also note that you need to first convert &y to unsafe.Pointer type
    and then convert that to *C.size_t. Go doesn't allow arbitrary
    conversion between pointer types, it must go through unsafe.Pointer.
    The problem is int is 32bit on 32bit platforms and will soon be 64bit on
    64bit platforms.
    uintptr also adjusts it's size based on target arch, which probably the
    reason size_t was created as well.
    --
  • Minux at Nov 15, 2012 at 7:29 am

    On Thu, Nov 15, 2012 at 4:23 AM, serbaut wrote:

    Not sure what you mean, the following runs fine with go tip:

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import "fmt"

    func main() {
    var x int32
    var y uint64
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(&y))
    fmt.Println(x, y)
    }
    this runs fine simply because size_t is an alias for uint64 on your system.

    in general, size_t should correspond to uintptr, and if you declare y as
    type uintptr, you
    need to use unsafe.Pointer to help converting &y to *C.size_t.

    --
  • Serbaut at Nov 16, 2012 at 8:08 pm
    I dont expect my code to be built on anything else than 64 bit linux but
    thanks for the explanations!

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import (
    "fmt"
    "unsafe"
    )

    func main() {
    var x int32
    var y uintptr
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(unsafe.Pointer(&y)))
    fmt.Println(x, y)
    }

    On Thursday, November 15, 2012 8:29:10 AM UTC+1, minux wrote:



    On Thu, Nov 15, 2012 at 4:23 AM, serbaut <ser...@gmail.com <javascript:>>wrote:
    Not sure what you mean, the following runs fine with go tip:

    package main

    // #include <stddef.h>
    // void foo(int *x) { *x = 17; }
    // void bar(size_t *y) { *y = 4711; }
    import "C"
    import "fmt"

    func main() {
    var x int32
    var y uint64
    C.foo((*C.int)(&x))
    C.bar((*C.size_t)(&y))
    fmt.Println(x, y)
    }
    this runs fine simply because size_t is an alias for uint64 on your system.

    in general, size_t should correspond to uintptr, and if you declare y as
    type uintptr, you
    need to use unsafe.Pointer to help converting &y to *C.size_t.
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 13, '12 at 10:32p
activeNov 16, '12 at 8:08p
posts8
users4
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase