Re: [go-nuts] Embedding Go in C apps?

986 views
Skip to first unread message

Krzysztof Kowalczyk

unread,
Oct 15, 2012, 7:12:20 PM10/15/12
to Jens Alfke, golan...@googlegroups.com
You can't do it, not today and possibly never.

The biggest problem is the fact that Go has its own runtime, namely a
garbage collector and a scheduler (for go routines) and segmented
stacks that do not play well with C stacks. It's much more complicated
than linking the executable code and translating between calling
conventions (e.g. what happens to a goroutine created in Go code you
called from C after Go code returns to C?)

Now, it's not impossible to overcome this e.g. V8 or Microsoft's .NET
have embedding APIs that allow for decent way of calling
JavaScript/CLR code from C/C++ code, but that doesn't exist for any
current implementation of Go (as far as I know) and doing it right is
significant amount of work.

-- kjk

On Mon, Oct 15, 2012 at 9:56 AM, Jens Alfke <je...@mooseyard.com> wrote:
> [This seems like it ought to be an FAQ, but I haven't seen it in any of the
> documentation, or in a cursory search of this list.]
>
> Some of the uses I'd like to put Go to involve writing a library in it,
> which would be statically linked into and called from traditional
> C/C++/Objective-C applications (primarily iOS / Mac OS. Is this feasible?
> I've only seen documentation about going the other direction, linking C
> libraries into a Go binary.
>
> When the Go compiler builds packages it creates .a files (on Darwin), but I
> haven't had any luck examining their contents with otool — I'm guessing that
> their contents aren't in a format that the regular Darwin toolchain
> understands. Either that or I just suck at otool, which is also plausible.
> :) I also understand that the Go calling conventions differ from C, so
> something CGo-like would have to be done to make entry points into the
> package that can be called from C code.
>
> --Jens
>
> --
>
>

Shane Hansen

unread,
Oct 15, 2012, 7:30:34 PM10/15/12
to Krzysztof Kowalczyk, Jens Alfke, golan...@googlegroups.com
The current best solution for embedding go in c apps is to embed the app in go.
That's not an option for most people, but basically there's nothing that keeps you from
writing a main.go that does something like:

/*
*/
import "C"
func main() {
C.main()
}

from that point on you can export go functions to c-world and vice versa.

--



Jens Alfke

unread,
Oct 15, 2012, 7:47:39 PM10/15/12
to Krzysztof Kowalczyk, golan...@googlegroups.com

On Oct 15, 2012, at 4:12 PM, Krzysztof Kowalczyk <kkowa...@gmail.com> wrote:

> The biggest problem is the fact that Go has its own runtime, namely a
> garbage collector and a scheduler (for go routines) and segmented
> stacks that do not play well with C stacks.

Understood, but as long as Go is using malloc to allocate its GC heap and stacks, it will play well with native code. Most other languages with complex runtimes support embedding in native/C processes (Lua, Java, Python, etc.)

> It's much more complicated
> than linking the executable code and translating between calling
> conventions (e.g. what happens to a goroutine created in Go code you
> called from C after Go code returns to C?)

Isn’t this also an issue when embedding C code in Go? I haven’t read the CGo docs closely, but I presume it supports callbacks where C code calls into Go.

—jens

Kevin Gillette

unread,
Oct 15, 2012, 8:31:06 PM10/15/12
to golan...@googlegroups.com, Krzysztof Kowalczyk
I know that C code embedded in a Go binary can use the malloc provided to it by Go, and be safe, but Go does not use 'malloc' in the sense that any generic malloc, or even the libc malloc, will necessarily work.  Additionally, Go may not be using the same malloc it provides to embedded C code.

Yes, C can call into Go (ala callbacks), but this probably requires an intermediate translation step before/during actual compilation, and so embedding "blindfolded" Go code in C, by compiling Go to object code, and then linking to that from C, probably won't work -- the community understands this as not working.

I don't think there's anything fundamental about Go that would prevent its runtime architecture from being naively embedded in C, but the existing tools don't now (and as mentioned, may never) be to the point where they can generate 'blindfold-safe' libraries. The llgo project may be closest to achieving this goal, since my impression is that the intermediate language generated by all clang frontends play nicer with each other than what you see on the gcc front.
Reply all
Reply to author
Forward
0 new messages