Ever since Go 1.5 came out, I started taking another look at how I could integrate it into an existing project of mine.
The project\'s codebase is written entirely i
To build an archive callable from C, you will need to mark them as exported CGo symbols.
For example, if I create a file foo.go
with the following contents:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x int) {
fmt.Println(x)
}
func main() {}
The important things to note are:
main
main
function, although it can be empty.C
//export
comments to mark the functions you want callable from C.I can compile it as a C callable static library with the following command:
go build -buildmode=c-archive foo.go
The results will be an archive foo.a
and a header foo.h
. In the header, we get the following (eliding irrelevant parts):
...
typedef long long GoInt64;
...
typedef GoInt64 GoInt;
...
extern void PrintInt(GoInt p0);
...
So that's enough to call the exported function. We can write a simple C program that calls it like so:
#include "foo.h"
int main(int argc, char **argv) {
PrintInt(42);
return 0;
}
We can compile it with a command like:
gcc -pthread foo.c foo.a -o foo
The -pthread
option is needed because the Go runtime makes use of threads. When I run the resulting executable it prints 42
.