Function Names#

Go code can call C functions directly using the //extern or //go:linkname compiler directives. An //extern directive must be at the beginning of the line and must start with //extern. This must be followed by a space and then the external name of the function. The function declaration must be on the line immediately after the comment. For example, here is how the C function open can be declared in Go:

//extern open
func c_open(name *byte, mode int, perm int) int

You can do the same thing using the //go:linkname compiler directive. The //go:linkname directive must be at the start of the line. It is followed by whitespace, the name of the Go function, more whitespace, and the external name of the function. Unlike //extern, //go:linkname does not need to appear immediately adjacent to the function definition or declaration.

//go:linkname c_open open
func c_open(name *byte, mode int, perm int) int

The C function naturally expects a nul terminated string, which in Go is equivalent to a pointer to an array (not a slice!) of byte with a terminating zero byte. So a sample call from Go would look like (after importing the os package):

var name = [4]byte{'f', 'o', 'o', 0};
i := c_open(&name[0], os.O_RDONLY, 0);

Note that this serves as an example only. To open a file in Go please use Go’s os.Open function instead.

The name of Go functions accessed from C is subject to change. At present the name of a Go function that does not have a receiver is pkgpath.Functionname. The pkgpath is set by the -fgo-pkgpath option used when the package is compiled; if the option is not used, the default is go.packagename. To call the function from C you must set the name using the gcc __asm__ extension.

extern int go_function(int) __asm__ ("mypkgpath.Function");