gocgo

How to pass a C function pointer around in go


I can pass a C function pointer to a C function, but passing it to a go function gives invalid operation.

I have 100 go functions wrapping C functions and most share the same setup and arguments so I wanted to implement one go function that can take a C function pointer to make this easier to maintain.

package main

/*
#include <stdio.h>
typedef void (*func_t)(int);
void this_works(int a, func_t f){
    f(a);
}
void tst(int a) {
    printf("YAY\n");
}
*/
import "C"

func this_does_not_work( fp C.func_t ) {
    fp(2) // invalid operation: cannot call non-function fp (variable of type _Ctype_func_t)
}

func main() {
    C.this_works(1, C.func_t(C.tst))
    this_does_not_work( C.func_t(C.tst) )
}

Solution

  • Impossible, but what's wrong with using a helper?

    package main
    
    /*
    #include <stdio.h>
    typedef void (*func_t)(int);
    void this_works(int a, func_t f){
        f(a);
    }
    void tst(int a) {
        printf("YAY\n");
    }
    
    void call_my_c_func(func_t f, int a)
    {
        f(a);
    }
    */
    import "C"
    
    func this_does_not_work(fp C.func_t) {
        C.call_my_c_func(fp, 2)
    }
    
    func main() {
        C.this_works(1, C.func_t(C.tst))
        this_does_not_work(C.func_t(C.tst))
    }
    

    Basically, you will use C.call_my_c_func(fp, a) instead of fp(a) where applicable—not very beautiful but works.