0

I have a C++ program that uses some go code compiled to a c library through cgo. I'd like to provide some C delegates / function pointers to the cgo library so that the go code can invoke some code provided by my C++ program. I find many examples how to call go functions from within C++ but nothing vice versa.

My go package looks like this

package main

import (
    "fmt"
    "unsafe"
)

/*
    #include <stdlib.h>
    typedef char* (*Callback)(char* args);
*/
import "C"

//export RegisterCallback
func RegisterCallback(funcptr unsafe.Pointer) {
    cstr := C.CString("hello from go")
    defer C.free(unsafe.Pointer(cstr))

    foo := *(*func(*C.char) *C.char)(funcptr)
    result := foo(cstr)

    fmt.Println(C.GoString((*C.char)(result)))
}

func main() {
}

and I am calling it from C++ like this

char* foo(char* args)
{
    std::cout << args;
    return "hello from C++";
}

//...
RegisterCallback((void*) &foo);

This, however, crashes badly within go.

6
  • 1
    C++ calling conventions are often tricky. To call a C++ function from Go, mark it as a C function (extern C) and add any special linkage requirements that your C++ compiler might require for this as well. Then you'll be calling a C function from Go, which is supported. Do not try to call it through a pointer. If you need to do that, export a C function wrapper that calls through a pointer. Commented Nov 22, 2020 at 0:55
  • I have the particular requirement to pass a function pointer, unfortunately. So I’d go through a C function, possibly with a payload. I am struggling how to pass that c function pointer to my go library and then, how to call it from go Commented Nov 22, 2020 at 8:05
  • C++ can always call C (and vice versa) using POD (stackoverflow.com/questions/146452/what-are-pod-types-in-c), and via cgo, you can call C from Go or vice versa, so that's the adaptation scheme. Commented Nov 22, 2020 at 8:31
  • great, to my understanding that's what I am doing by passing a pointer. Looking at my code in the question, can you spot anything that is obviously wrong? Appreciate it! Commented Nov 22, 2020 at 8:38
  • 1
    You're taking a function pointer (&foo) and converting it to a data pointer (void *). The only guarantee you get is that you can call a C function (not C++ function) by name, so that's what you have to do: CallC(args). That function, written in plain C (not C++), can take the arguments and use them to pick which C++ function to call in whatever way your C and C++ code are allowed to cooperate by your compilation system. Commented Nov 22, 2020 at 23:32

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.