5 ms·
At the bottom of the cgo command documentation [0] is an example of exporting go functions to C. I don't fully understand how those functions work when running
by Arnor 13y ago
At the bottom of the cgo command documentation [0] is an example of exporting go functions to C. I don't fully understand how those functions work when running in C land (does the GC come with?), but the implementation doesn't look difficult.
[0] http://golang.org/cmd/cgo/ http://golang.org/cmd/cgo/
- timtadh 13y agoHow it works (from http://golang.org/src/pkg/runtime/cgocall.c http://golang.org/src/pkg/runtime/cgocall.c ) 36 // The above description skipped over the possibility of the gcc-compiled 37 // function f calling back into Go. If that happens, we continue down 38 // the rabbit hole during the execution of f. 39 // 40 // To make it possible for gcc-compiled C code to call a Go function p.GoF, 41 // cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't 42 // know about packages). The gcc-compiled C function f calls GoF. 43 // 44 // GoF calls crosscall2(_cgoexp_GoF, frame, framesize). Crosscall2 45 // (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument 46 // adapter from the gcc function call ABI to the 6c function call ABI. 47 // It is called from gcc to call 6c functions. In this case it calls 48 // _cgoexp_GoF(frame, framesize), still running on m->g0's stack 49 // and outside the $GOMAXPROCS limit. Thus, this code cannot yet 50 // call arbitrary Go code directly and must be careful not to allocate 51 // memory or use up m->g0's stack. 52 // 53 // _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize). 54 // (The reason for having _cgoexp_GoF instead of writing a crosscall3 55 // to make this call directly is that _cgoexp_GoF, because it is compiled 56 // with 6c instead of gcc, can refer to dotted names like 57 // runtime.cgocallback and p.GoF.) 58 // 59 // runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's 60 // stack to the original g (m->curg)'s stack, on which it calls 61 // runtime.cgocallbackg(p.GoF, frame, framesize). 62 // As part of the stack switch, runtime.cgocallback saves the current 63 // SP as m->g0->sched.sp, so that any use of m->g0's stack during the 64 // execution of the callback will be done below the existing stack frames. 65 // Before overwriting m->g0->sched.sp, it pushes the old value on the 66 // m->g0 stack, so that it can be restored later. 67 // 68 // runtime.cgocallbackg (below) is now running on a real goroutine 69 // stack (not an m->g0 stack). First it calls runtime.exitsyscall, which will 70 // block until the $GOMAXPROCS limit allows running this goroutine. 71 // Once exitsyscall has returned, it is safe to do things like call the memory 72 // allocator or invoke the Go callback function p.GoF. runtime.cgocallbackg 73 // first defers a function to unwind m->g0.sched.sp, so that if p.GoF 74 // panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack 75 // and the m->curg stack will be unwound in lock step. 76 // Then it calls p.GoF. Finally it pops but does not execute the deferred 77 // function, calls runtime.entersyscall, and returns to runtime.cgocallback. 78 // 79 // After it regains control, runtime.cgocallback switches back to 80 // m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old 81 // m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF. 82 // 83 // _cgoexp_GoF immediately returns to crosscall2, which restores the 84 // callee-save registers for gcc and returns to GoF, which returns to f.
- lmkg 13y agoI'm not particularly familiar with either language... that documentation seems to be talking only about Go called from C-called-from-Go, not from arbitrary C. In other words, it handles Go calling a C function that expects a callback, and handing it a Go function. This does not handle a fundamentally-C program calling a Go function. Again, not an expert, I could be mistaken, but this seems to not be addressing the original issue raised (that C/Go interop is one-way only).
- AYBABTME 13y agoWhat you can do: - Have some C code in your Go app that calls a Go function. What you can't do: - Have some C code in your C app that calls a Go function.
- Arnor 13y agoThe second answer to this stack overflow [0] indicates that you can run Go functions from C if you use gccgo [1]. [0] http://stackoverflow.com/questions/6125683/call-go-functions-from-c http://stackoverflow.com/questions/6125683/call-go-functions... [1] http://golang.org/doc/install/gccgo http://golang.org/doc/install/gccgo