passing function pointer to the C code using cgo

Iakov Davydov :

Starting from Go v1.6 cgo changed the rules of passing pointers to the C code golang/go#12416. The example of invoking a dynamic Go callback from C code from the wiki doesn't work anymore.

package main

import (
    "fmt"
    "unsafe"
)

/*
   extern void go_callback_int(void* foo, int p1);

   // normally you will have to define function or variables
   // in another separate C file to avoid the multiple definition
   // errors, however, using "static inline" is a nice workaround
   // for simple functions like this one.
   static inline void CallMyFunction(void* pfoo) {
       go_callback_int(pfoo, 5);
       }
*/
import "C"

//export go_callback_int
func go_callback_int(pfoo unsafe.Pointer, p1 C.int) {
    foo := *(*func(C.int))(pfoo)
    foo(p1)
}

func MyCallback(x C.int) {
    fmt.Println("callback with", x)
}

// we store it in a global variable so that the garbage collector
// doesn't clean up the memory for any temporary variables created.
var MyCallbackFunc = MyCallback

func Example() {
    C.CallMyFunction(unsafe.Pointer(&MyCallbackFunc))
}

func main() {
    Example()
}

The output looks like this:

panic: runtime error: cgo argument has Go pointer to Go pointer

What is the proper way to do this today? Preferably without hacks like hiding pointer from the language by converting it into uintptr_t.

Iakov Davydov :

Starting from Go 1.6 cgo has new rules.

Go code may pass a Go pointer to C provided that the Go memory to which it points does not contain any Go pointers.

[source]

These rules are checked during the runtime, and if violated program crashes. At the moment it is possible to disable checks using GODEBUG=cgocheck=0 environment variable. But in the future, that might stop working.

So it is not possible anymore to pass a pointer to C code, if the memory to which it is pointing stores a Go function/method pointer. There are several ways to overcome this limitations, but I guess in most of them you should store a synchronized data structure which represents the correspondence between a certain id and the actual pointer. This way you can pass an id to the C code, not a pointer.

The code solving this problem might look like this:

package gocallback

import (
    "fmt"
    "sync"
)

/*
extern void go_callback_int(int foo, int p1);

// normally you will have to define function or variables
// in another separate C file to avoid the multiple definition
// errors, however, using "static inline" is a nice workaround
// for simple functions like this one.
static inline void CallMyFunction(int foo) {
    go_callback_int(foo, 5);
}
*/
import "C"

//export go_callback_int
func go_callback_int(foo C.int, p1 C.int) {
    fn := lookup(int(foo))
    fn(p1)
}

func MyCallback(x C.int) {
    fmt.Println("callback with", x)
}

func Example() {
    i := register(MyCallback)
    C.CallMyFunction(C.int(i))
    unregister(i)
}

var mu sync.Mutex
var index int
var fns = make(map[int]func(C.int))

func register(fn func(C.int)) int {
    mu.Lock()
    defer mu.Unlock()
    index++
    for fns[index] != nil {
        index++
    }
    fns[index] = fn
    return index
}

func lookup(i int) func(C.int) {
    mu.Lock()
    defer mu.Unlock()
    return fns[i]
}

func unregister(i int) {
    mu.Lock()
    defer mu.Unlock()
    delete(fns, i)
}

This code comes from the (updated) wiki page.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From

Calling a C function with a double pointer output parameter using CGo

From Dev

C - Passing pointer to function

From Dev

passing pointer to function and using realloc

From Dev

Python -passing imgdata pointer to a function in C using ctypes

From Dev

Passing a pointer to an array in a function in C

From Dev

C++ passing function pointer

From Dev

Passing Function Pointer in C#

From Dev

Passing a pointer (string) to a C function

From Dev

confusion in passing a pointer to function in C

From Dev

Passing pointer of an array to a function in C

From Dev

passing a pointer through a function c

From Dev

C++: Passing lambda pointer as a function pointer

From Dev

passing function pointer in c with a pointer argument

From Dev

Passing single pointer and double pointer to a function in c

From

Why CGO can't directly call function pointer in C?

From Dev

Boost C++. Passing a member function pointer with signature pointer to function

From Dev

Passing a Delegate to a callback function in unmanaged code using c#

From Dev

Passing by pointer a struct instance initialized within one function on to another function in C yields different results using GCC

From Dev

Passing Array of Structs to a Function as a Pointer (C)

From Dev

passing a pointer of different type to a function (C)

From Dev

C++ crashing when passing pointer to function

From Dev

Passing pointer to an array into a function (C++)

From Dev

Passing a C function pointer to emscripten callback

From Dev

Passing pointer to function that accepts reference in c++

From Dev

Passing a safe rust function pointer to C

From Dev

Passing in an element in an array as a pointer in a function in C

From Dev

Properly passing pointer from function C++

From Dev

C - Passing a pointer to an array to a function to print the array

From Dev

c struct passing itself as an argument into a pointer function

Related Related

  1. 1

    Calling a C function with a double pointer output parameter using CGo

  2. 2

    C - Passing pointer to function

  3. 3

    passing pointer to function and using realloc

  4. 4

    Python -passing imgdata pointer to a function in C using ctypes

  5. 5

    Passing a pointer to an array in a function in C

  6. 6

    C++ passing function pointer

  7. 7

    Passing Function Pointer in C#

  8. 8

    Passing a pointer (string) to a C function

  9. 9

    confusion in passing a pointer to function in C

  10. 10

    Passing pointer of an array to a function in C

  11. 11

    passing a pointer through a function c

  12. 12

    C++: Passing lambda pointer as a function pointer

  13. 13

    passing function pointer in c with a pointer argument

  14. 14

    Passing single pointer and double pointer to a function in c

  15. 15

    Why CGO can't directly call function pointer in C?

  16. 16

    Boost C++. Passing a member function pointer with signature pointer to function

  17. 17

    Passing a Delegate to a callback function in unmanaged code using c#

  18. 18

    Passing by pointer a struct instance initialized within one function on to another function in C yields different results using GCC

  19. 19

    Passing Array of Structs to a Function as a Pointer (C)

  20. 20

    passing a pointer of different type to a function (C)

  21. 21

    C++ crashing when passing pointer to function

  22. 22

    Passing pointer to an array into a function (C++)

  23. 23

    Passing a C function pointer to emscripten callback

  24. 24

    Passing pointer to function that accepts reference in c++

  25. 25

    Passing a safe rust function pointer to C

  26. 26

    Passing in an element in an array as a pointer in a function in C

  27. 27

    Properly passing pointer from function C++

  28. 28

    C - Passing a pointer to an array to a function to print the array

  29. 29

    c struct passing itself as an argument into a pointer function

HotTag

Archive