FAQ
I'm calling a C function that returns a float** value which I want to
copy into a Go slice, but am getting an indexing error.

The code looks something like:

  var cpix **C.float = C.readPixels(infile)
  defer C.free(unsafe.Pointer(cpix))
  pix := make([]float32, n)
  for i := 0; i < n; i++ {
   pix[i] = cpix[i]
  }

but the error I'm getting is: invalid operation: cpix[i] (index of
type **_Ctype_float)

So seems like I can't do indexing into C arrays from Go.

Thanks for any help.

   John

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Minux at Mar 6, 2013 at 11:38 am

    On Wed, Mar 6, 2013 at 7:28 PM, John Barham wrote:

    I'm calling a C function that returns a float** value which I want to
    copy into a Go slice, but am getting an indexing error.

    The code looks something like:

    var cpix **C.float = C.readPixels(infile)
    defer C.free(unsafe.Pointer(cpix))
    pix := make([]float32, n)
    for i := 0; i < n; i++ {
    pix[i] = cpix[i]
    }

    but the error I'm getting is: invalid operation: cpix[i] (index of
    type **_Ctype_float)

    So seems like I can't do indexing into C arrays from Go.
    Go doesn't have pointer arithmetic and so it can't do access like this
    pointer[index], because
    that means *(pointer + index) [another reason is that a pointer doesn't
    contain a limit for index,
    so allowing that will effectively make unconstrained memory access
    possible].

    you have a few alternatives here (take C's "int *p" as an example):
    1. the hard one: cast the pointer into unsafe.Pointer and then uintptr, do
    the pointer arithmetic
    (remember you need uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(C.int(0)) * i
    to take size of int
    into account) and then cast it back to a pointer through unsafe.Pointer.

    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].

    special notice: Go's int type is not necessarily the same as C's, so be
    aware.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Rémy Oudompheng at Mar 6, 2013 at 11:51 am
    It is also possible to make() a Go slice and use C.memcpy to fill it
    (with the same unsafeties as the other methods).

    Rémy.

    2013/3/6, minux <minux.ma@gmail.com>:
    On Wed, Mar 6, 2013 at 7:28 PM, John Barham wrote:

    I'm calling a C function that returns a float** value which I want to
    copy into a Go slice, but am getting an indexing error.

    The code looks something like:

    var cpix **C.float = C.readPixels(infile)
    defer C.free(unsafe.Pointer(cpix))
    pix := make([]float32, n)
    for i := 0; i < n; i++ {
    pix[i] = cpix[i]
    }

    but the error I'm getting is: invalid operation: cpix[i] (index of
    type **_Ctype_float)

    So seems like I can't do indexing into C arrays from Go.
    Go doesn't have pointer arithmetic and so it can't do access like this
    pointer[index], because
    that means *(pointer + index) [another reason is that a pointer doesn't
    contain a limit for index,
    so allowing that will effectively make unconstrained memory access
    possible].

    you have a few alternatives here (take C's "int *p" as an example):
    1. the hard one: cast the pointer into unsafe.Pointer and then uintptr, do
    the pointer arithmetic
    (remember you need uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(C.int(0)) * i
    to take size of int
    into account) and then cast it back to a pointer through unsafe.Pointer.

    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].

    special notice: Go's int type is not necessarily the same as C's, so be
    aware.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Gordon Klaus at Mar 6, 2013 at 3:08 pm
    You can avoid the copy by just making a slice point to your data:
    var pix []float32
    h := (*reflect.SliceHeader)(unsafe.Pointer(&pix))
    h.Data = uintptr(unsafe.Pointer(cpix))
    h.Len = n
    h.Cap = n
    But then you have to be sure not to free cpix before you're done using pix.
      Go will not manage memory that it didn't allocate.

    On Wednesday, March 6, 2013 6:51:15 AM UTC-5, Rémy Oudompheng wrote:

    It is also possible to make() a Go slice and use C.memcpy to fill it
    (with the same unsafeties as the other methods).

    Rémy.

    2013/3/6, minux <minu...@gmail.com <javascript:>>:
    On Wed, Mar 6, 2013 at 7:28 PM, John Barham wrote:

    I'm calling a C function that returns a float** value which I want to
    copy into a Go slice, but am getting an indexing error.

    The code looks something like:

    var cpix **C.float = C.readPixels(infile)
    defer C.free(unsafe.Pointer(cpix))
    pix := make([]float32, n)
    for i := 0; i < n; i++ {
    pix[i] = cpix[i]
    }

    but the error I'm getting is: invalid operation: cpix[i] (index of
    type **_Ctype_float)

    So seems like I can't do indexing into C arrays from Go.
    Go doesn't have pointer arithmetic and so it can't do access like this
    pointer[index], because
    that means *(pointer + index) [another reason is that a pointer doesn't
    contain a limit for index,
    so allowing that will effectively make unconstrained memory access
    possible].

    you have a few alternatives here (take C's "int *p" as an example):
    1. the hard one: cast the pointer into unsafe.Pointer and then uintptr, do
    the pointer arithmetic
    (remember you need uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(C.int(0)) * i
    to take size of int
    into account) and then cast it back to a pointer through unsafe.Pointer.

    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].

    special notice: Go's int type is not necessarily the same as C's, so be
    aware.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • John Barham at Mar 6, 2013 at 10:12 pm

    On Wed, Mar 6, 2013 at 10:37 PM, minux wrote:
    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].
    This is working for me, with addition of extra parens around
    unsafe.Pointer: p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    Many thanks!

       John

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Herbert Fischer at May 3, 2013 at 1:04 am
    I'm getting into the same issue but I would like to understand better what
    this line means:

    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??

    On 6 March 2013 19:12, John Barham wrote:
    On Wed, Mar 6, 2013 at 10:37 PM, minux wrote:
    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].
    This is working for me, with addition of extra parens around
    unsafe.Pointer: p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    Many thanks!

    John

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Herbert Fischer at May 3, 2013 at 1:15 am
    Nevermind. Already got it.

    On 2 May 2013 22:04, Herbert Fischer wrote:

    I'm getting into the same issue but I would like to understand better what
    this line means:

    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??

    On 6 March 2013 19:12, John Barham wrote:
    On Wed, Mar 6, 2013 at 10:37 PM, minux wrote:
    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].
    This is working for me, with addition of extra parens around
    unsafe.Pointer: p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    Many thanks!

    John

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Camilo Aguilar at Nov 5, 2013 at 4:30 pm
    I still don't get 1<<30, what does it do?
    On Thursday, May 2, 2013 9:14:50 PM UTC-4, Herbert Fischer wrote:

    Nevermind. Already got it.


    On 2 May 2013 22:04, Herbert Fischer <herbert...@gmail.com <javascript:>>wrote:
    I'm getting into the same issue but I would like to understand better
    what this line means:

    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??


    On 6 March 2013 19:12, John Barham <jba...@gmail.com <javascript:>>wrote:
    On Wed, Mar 6, 2013 at 10:37 PM, minux <minu...@gmail.com <javascript:>>
    wrote:
    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].
    This is working for me, with addition of extra parens around
    unsafe.Pointer: p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    Many thanks!

    John

    --
    You received this message because you are subscribed to the Google
    Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send
    an email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Chris dollin at Nov 5, 2013 at 4:51 pm

    On 5 November 2013 16:30, Camilo Aguilar wrote:

    I still don't get 1<<30, what does it do?
    << is bit shift left; each shift multiplies by 2, so 1 << 30 is 2
    to-the-power-of 30, a computational billion.

    (And the (*[1<<30]C.int) is a type which is "pointer to a billion-C-int
    array".)

    On Thursday, May 2, 2013 9:14:50 PM UTC-4, Herbert Fischer wrote:

    Nevermind. Already got it.

    On 2 May 2013 22:04, Herbert Fischer wrote:

    I'm getting into the same issue but I would like to understand better
    what this line means:

    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??

    On 6 March 2013 19:12, John Barham wrote:
    On Wed, Mar 6, 2013 at 10:37 PM, minux wrote:
    2. make the pointer a pointer to a large Go array.
    p2 := (*[1<<30]C.int)unsafe.Pointer(p)
    then you can use p2[index] to access p[index].
    This is working for me, with addition of extra parens around
    unsafe.Pointer: p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    Many thanks!

    John

    --
    You received this message because you are subscribed to the Google
    Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send
    an email to golang-nuts...@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.


    --
    Chris "allusive" Dollin

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Nov 5, 2013 at 5:00 pm

    On Nov 5, 2013 11:30 AM, "Camilo Aguilar" wrote:
    I still don't get 1<<30, what does it do?
    just an arbitrary big number (hopefully big enough for your slice
    length/capacity) for the length of the array, so that you can slice it with
    the length you want.
    On Thursday, May 2, 2013 9:14:50 PM UTC-4, Herbert Fischer wrote:

    Nevermind. Already got it.
    On 2 May 2013 22:04, Herbert Fischer wrote:

    I'm getting into the same issue but I would like to understand better
    what this line means:
    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Camilo Aguilar at Nov 5, 2013 at 7:17 pm
    how would it be if I know the length of the C array?
    On Tuesday, November 5, 2013 12:00:33 PM UTC-5, minux wrote:

    On Nov 5, 2013 11:30 AM, "Camilo Aguilar" wrote:
    I still don't get 1<<30, what does it do?
    just an arbitrary big number (hopefully big enough for your slice
    length/capacity) for the length of the array, so that you can slice it with
    the length you want.
    On Thursday, May 2, 2013 9:14:50 PM UTC-4, Herbert Fischer wrote:

    Nevermind. Already got it.
    On 2 May 2013 22:04, Herbert Fischer wrote:

    I'm getting into the same issue but I would like to understand better
    what this line means:
    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Nov 5, 2013 at 7:27 pm

    On Nov 5, 2013 2:17 PM, "Camilo Aguilar" wrote:
    how would it be if I know the length of the C array?
    it you know the length statically (that you can write down the number in
    source code as a constant), you can use that constant as the array length.

    but if it is stored in a variable, you will have to use the 1<<30 trick,
    because arrays in Go must have statically determined bounds.
    On Tuesday, November 5, 2013 12:00:33 PM UTC-5, minux wrote:
    On Nov 5, 2013 11:30 AM, "Camilo Aguilar" wrote:
    I still don't get 1<<30, what does it do?
    just an arbitrary big number (hopefully big enough for your slice
    length/capacity) for the length of the array, so that you can slice it with
    the length you want.
    On Thursday, May 2, 2013 9:14:50 PM UTC-4, Herbert Fischer wrote:

    Nevermind. Already got it.
    On 2 May 2013 22:04, Herbert Fischer wrote:

    I'm getting into the same issue but I would like to understand
    better what this line means:
    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Camilo Aguilar at Nov 5, 2013 at 7:35 pm
    I see... I believe I understand better now, thank for for your quick
    response!.
    On Tuesday, November 5, 2013 2:27:38 PM UTC-5, minux wrote:

    On Nov 5, 2013 2:17 PM, "Camilo Aguilar" wrote:

    how would it be if I know the length of the C array?
    it you know the length statically (that you can write down the number in
    source code as a constant), you can use that constant as the array length.

    but if it is stored in a variable, you will have to use the 1<<30 trick,
    because arrays in Go must have statically determined bounds.
    On Tuesday, November 5, 2013 12:00:33 PM UTC-5, minux wrote:
    On Nov 5, 2013 11:30 AM, "Camilo Aguilar" wrote:
    I still don't get 1<<30, what does it do?
    just an arbitrary big number (hopefully big enough for your slice
    length/capacity) for the length of the array, so that you can slice it with
    the length you want.
    On Thursday, May 2, 2013 9:14:50 PM UTC-4, Herbert Fischer wrote:

    Nevermind. Already got it.
    On 2 May 2013 22:04, Herbert Fischer wrote:

    I'm getting into the same issue but I would like to understand
    better what this line means:
    p2 := (*[1<<30]C.int)(unsafe.Pointer(p)).

    specially: (*[1<<30]C.int) - why 1<<30 ??
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 6, '13 at 11:28a
activeNov 5, '13 at 7:35p
posts13
users7
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase