FAQ
My question is similar to the original question asked by this stackoverflow
post
<http://stackoverflow.com/questions/10728197/cgo-getting-a-float32-from-c-float>.
  Basically how would I be able to pass in a multiple dimensional byte
([][]byte) array such that it could be read by my C code.

The Go code compiles and runs, but crashes within the C code which just
reads the array like below. My C code is working, I'm just having trouble
passing the pointer correctly.

Passing in a [][]byte multiple dimensional array into this C psuedocode
function

void getMatrix(unsigned char **matrix) {
         for (j = 0; j < srcs; j++) {
                 for (i = 0; i < len; i++) {
                      s = src[j][i];
                 }
         }
}


with this Go psuedocode

import "C"
import "unsafe"

func Hello() {
sources := make([][]byte, k)
for i := range sources {
sources[i] = make([]byte, sourceLength)
}
C.getMatrix((**C.uchar)(unsafe.Pointer(&sources[0])))
}


The problem I am having is casting the Go [][]byte array correctly to the C
unsigned char** correctly. Any ideas? Can this be done? Would a single
dimensional array be better?

--
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/d/optout.

Search Discussions

  • Egon at Oct 31, 2014 at 8:55 am

    On Friday, 31 October 2014 07:34:53 UTC+2, Peter C wrote:
    My question is similar to the original question asked by this stackoverflow
    post
    <http://stackoverflow.com/questions/10728197/cgo-getting-a-float32-from-c-float>.
    Basically how would I be able to pass in a multiple dimensional byte
    ([][]byte) array such that it could be read by my C code.

    The Go code compiles and runs, but crashes within the C code which just
    reads the array like below. My C code is working, I'm just having trouble
    passing the pointer correctly.

    Passing in a [][]byte multiple dimensional array into this C psuedocode
    function

    void getMatrix(unsigned char **matrix) {
    for (j = 0; j < srcs; j++) {
    for (i = 0; i < len; i++) {
    s = src[j][i];
    }
    }
    }


    with this Go psuedocode

    import "C"
    import "unsafe"

    func Hello() {
    sources := make([][]byte, k)
    for i := range sources {
    sources[i] = make([]byte, sourceLength)
    }
    C.getMatrix((**C.uchar)(unsafe.Pointer(&sources[0])))
    }


    The problem I am having is casting the Go [][]byte array correctly to the
    C unsigned char** correctly. Any ideas? Can this be done? Would a single
    dimensional array be better?
    First take a look at how slices are stored internally:
    http://blog.golang.org/go-slices-usage-and-internals
    http://research.swtch.com/godata
    https://code.google.com/p/go-wiki/wiki/cgo

    It should give you an idea why it doesn't work.

    Yes, a single dimensional array would be better.

    Essentially write your C function as:
    getMatrix(unsigned char *matrix, int ncols, int nrows)

    And keep the Go matrix in a single array []byte.

    Also ensure that array doesn't get prematurely garbage collected.

    sources := make([]byte, 100)
    data := unsafe.Pointer(&sources[0])
    C.getMatrix((*C.uchar)(data), 10, 10)
    _ = data

    I can't remember the exact rules how to properly pass pointers to C, but it
    probably is covered in some thread/page.

    + egon

    --
    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/d/optout.
  • Stephen Gutekanst at Oct 31, 2014 at 8:57 am
    Perhaps without understanding why, the reason that you write:

    unsafe.Pointer(&sources[0])


    Is because slices have a *slice header*, you can see an effective slice
    header definition in Go's reflect
    package: http://golang.org/pkg/reflect/#SliceHeader

    When you get a pointer to the first element in a slice, you're grabbing a
    pointer to the *start of the slice's data*.

    Now, in your C code you are treating slices as if they are arrays: they are
    not. [][]byte and **uchar are two totally separate things.

    A single dimensional array would simplify the problem, yes. Mainly you just
    need to acknowledge the slice header in your C code.

    - Stephen
    On Thursday, October 30, 2014 10:34:53 PM UTC-7, Peter C wrote:

    My question is similar to the original question asked by this stackoverflow
    post
    <http://stackoverflow.com/questions/10728197/cgo-getting-a-float32-from-c-float>.
    Basically how would I be able to pass in a multiple dimensional byte
    ([][]byte) array such that it could be read by my C code.

    The Go code compiles and runs, but crashes within the C code which just
    reads the array like below. My C code is working, I'm just having trouble
    passing the pointer correctly.

    Passing in a [][]byte multiple dimensional array into this C psuedocode
    function

    void getMatrix(unsigned char **matrix) {
    for (j = 0; j < srcs; j++) {
    for (i = 0; i < len; i++) {
    s = src[j][i];
    }
    }
    }


    with this Go psuedocode

    import "C"
    import "unsafe"

    func Hello() {
    sources := make([][]byte, k)
    for i := range sources {
    sources[i] = make([]byte, sourceLength)
    }
    C.getMatrix((**C.uchar)(unsafe.Pointer(&sources[0])))
    }


    The problem I am having is casting the Go [][]byte array correctly to the
    C unsigned char** correctly. Any ideas? Can this be done? Would a single
    dimensional array be better?
    --
    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/d/optout.
  • peterGo at Oct 31, 2014 at 10:04 am
    Peter,

    A multidimensional array is not the same as a multidimensional slice.
    Construct the multidimensional slice so that it uses a multidimensional
    array as its underlying array. For example,

    Playground: http://play.golang.org/p/hbrh1iF1w_

    Then you can write

         C.getMatrix((**C.uchar)(unsafe.Pointer(CMatrixPtr(matrix))))

    Peter
    On Friday, October 31, 2014 1:34:53 AM UTC-4, Peter C wrote:

    My question is similar to the original question asked by this stackoverflow
    post
    <http://stackoverflow.com/questions/10728197/cgo-getting-a-float32-from-c-float>.
    Basically how would I be able to pass in a multiple dimensional byte
    ([][]byte) array such that it could be read by my C code.

    The Go code compiles and runs, but crashes within the C code which just
    reads the array like below. My C code is working, I'm just having trouble
    passing the pointer correctly.

    Passing in a [][]byte multiple dimensional array into this C psuedocode
    function

    void getMatrix(unsigned char **matrix) {
    for (j = 0; j < srcs; j++) {
    for (i = 0; i < len; i++) {
    s = src[j][i];
    }
    }
    }


    with this Go psuedocode

    import "C"
    import "unsafe"

    func Hello() {
    sources := make([][]byte, k)
    for i := range sources {
    sources[i] = make([]byte, sourceLength)
    }
    C.getMatrix((**C.uchar)(unsafe.Pointer(&sources[0])))
    }


    The problem I am having is casting the Go [][]byte array correctly to the
    C unsigned char** correctly. Any ideas? Can this be done? Would a single
    dimensional array be better?
    --
    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/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedOct 31, '14 at 7:14a
activeOct 31, '14 at 10:04a
posts4
users4
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase