FAQ
I have a go function that takes ...interface{} arguments and I need to call
a C function with pointers to (the value of) each of the arguments.

Is the following code safe (taking the address of the type switched value)?
Is there an better way of doing it?

(I am not concerned about what the C function does with the arguments, just
the invocation from go).

package main

// void f(void **args) { }
import "C"

import "unsafe"

func callf(args ...interface{}) {
params := make([]unsafe.Pointer, len(args))
for i := range args {
switch v := args[i].(type) {
case int32:
params[i] = unsafe.Pointer(&v)
case float32:
params[i] = unsafe.Pointer(&v)
case float64:
params[i] = unsafe.Pointer(&v)
default:
panic("invalid argument")
}
}

C.f(&params[0])
}

func main() {
callf(int32(1), float32(2.0), 3.0)
}

--

Search Discussions

  • Ian Lance Taylor at Nov 20, 2012 at 5:04 pm

    On Tue, Nov 20, 2012 at 9:01 AM, serbaut wrote:
    I have a go function that takes ...interface{} arguments and I need to call
    a C function with pointers to (the value of) each of the arguments.

    Is the following code safe (taking the address of the type switched value)?
    Is there an better way of doing it?

    (I am not concerned about what the C function does with the arguments, just
    the invocation from go).

    package main

    // void f(void **args) { }
    import "C"

    import "unsafe"

    func callf(args ...interface{}) {
    params := make([]unsafe.Pointer, len(args))
    for i := range args {
    switch v := args[i].(type) {
    case int32:
    params[i] = unsafe.Pointer(&v)
    case float32:
    params[i] = unsafe.Pointer(&v)
    case float64:
    params[i] = unsafe.Pointer(&v)
    default:
    panic("invalid argument")
    }
    }

    C.f(&params[0])
    }

    func main() {
    callf(int32(1), float32(2.0), 3.0)
    }

    Sure, that is fine. Of course the Go garbage collector is going to
    free those pointers some time after the function callf returns, so
    your C code had better not be saving the pointers.

    Ian

    --
  • Serbaut at Nov 20, 2012 at 5:32 pm
    Thanks! I'm assuming it wont save the pointers (its a 3rd party library so
    no source :P)
    On Tuesday, November 20, 2012 6:04:49 PM UTC+1, Ian Lance Taylor wrote:

    On Tue, Nov 20, 2012 at 9:01 AM, serbaut <[email protected] <javascript:>>
    wrote:
    I have a go function that takes ...interface{} arguments and I need to call
    a C function with pointers to (the value of) each of the arguments.

    Is the following code safe (taking the address of the type switched value)?
    Is there an better way of doing it?

    (I am not concerned about what the C function does with the arguments, just
    the invocation from go).

    package main

    // void f(void **args) { }
    import "C"

    import "unsafe"

    func callf(args ...interface{}) {
    params := make([]unsafe.Pointer, len(args))
    for i := range args {
    switch v := args[i].(type) {
    case int32:
    params[i] = unsafe.Pointer(&v)
    case float32:
    params[i] = unsafe.Pointer(&v)
    case float64:
    params[i] = unsafe.Pointer(&v)
    default:
    panic("invalid argument")
    }
    }

    C.f(&params[0])
    }

    func main() {
    callf(int32(1), float32(2.0), 3.0)
    }

    Sure, that is fine. Of course the Go garbage collector is going to
    free those pointers some time after the function callf returns, so
    your C code had better not be saving the pointers.

    Ian
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 20, '12 at 5:01p
activeNov 20, '12 at 5:32p
posts3
users2
websitegolang.org

2 users in discussion

Serbaut: 2 posts Ian Lance Taylor: 1 post

People

Translate

site design / logo © 2023 Grokbase