blob: 48fd2993edf410af0da74163ae96b618b1e5b686 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Introduction
2
3First, http://golang.org/cmd/cgo is the primary cgo documentation.
4
5There is also a good introduction article at http://golang.org/doc/articles/c_go_cgo.html.
6
7## The basics
8
9If a Go source file imports ` "C" `, it is using cgo. The Go file will have access to anything appearing in the comment immediately preceding the line ` import "C" `, and will be linked against all other cgo comments in other Go files, and all C files included in the build process.
10
11Note that there must be no blank lines in between the cgo comment and the import statement.
12
nathany86c47cc2014-12-10 09:43:20 -080013To access a symbol originating from the C side, use the package name ` C `. That is, if you want to call the C function ` printf() ` from Go code, you write ` C.printf() `. Since variable argument methods like printf aren't supported yet (issue [975](https://github.com/golang/go/issues/975)), we will wrap it in the C method "myprint":
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110014
nathany86c47cc2014-12-10 09:43:20 -080015```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110016package cgoexample
17
18/*
19#include <stdio.h>
20#include <stdlib.h>
21
22void myprint(char* s) {
23 printf("%s", s);
24}
25*/
26import "C"
27
28import "unsafe"
29
30func Example() {
31 cs := C.CString("Hello from stdio\n")
32 C.myprint(cs)
33 C.free(unsafe.Pointer(cs))
34}
35```
36
37## Calling Go functions from C
38
39It is possible to call both top-level Go functions and function variables from C code invoked from Go code using cgo.
40
41### Global functions
42
43Go makes its functions available to C code through use of a special ` //export ` comment.
44Note: you can't define any C functions in preamble if you're using exports.
45
46For example, there are two files, foo.c and foo.go:
47foo.go contains:
nathany86c47cc2014-12-10 09:43:20 -080048
49```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110050package gocallback
51
52import "fmt"
53
54/*
55#include <stdio.h>
56extern void ACFunction();
57*/
58import "C"
59
60//export AGoFunction
61func AGoFunction() {
62 fmt.Println("AGoFunction()")
63}
64
65func Example() {
66 C.ACFunction()
67}
68```
nathany86c47cc2014-12-10 09:43:20 -080069
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110070foo.c contains:
nathany86c47cc2014-12-10 09:43:20 -080071
72```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110073#include "_cgo_export.h"
74void ACFunction() {
75 printf("ACFunction()\n");
76 AGoFunction();
77}
78```
79
80### Function variables
81
82The following code shows an example of invoking a Go callback from C code. Go passes the function variable to the CGo code by calling ` CallMyFunction() `. ` CallMyFunction() ` invokes the callback by sending it back into the Go code, with the desired parameters, for unpacking and calling.
83
nathany86c47cc2014-12-10 09:43:20 -080084```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110085package gocallback
86
87import (
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110088 "fmt"
Dave Day0d6986a2014-12-10 15:02:18 +110089 "unsafe"
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110090)
91
92/*
93extern void go_callback_int(void* foo, int p1);
94
95// normally you will have to define function or variables
96// in another separate C file to avoid the multiple definition
97// errors, however, using "static inline" is a nice workaround
98// for simple functions like this one.
99static inline void CallMyFunction(void* pfoo) {
100 go_callback_int(pfoo, 5);
101}
102*/
103import "C"
104
105//export go_callback_int
106func go_callback_int(pfoo unsafe.Pointer, p1 C.int) {
107 foo := *(*func(C.int))(pfoo)
108 foo(p1)
109}
110
111func MyCallback(x C.int) {
112 fmt.Println("callback with", x)
113}
114
115// we store it in a global variable so that the garbage collector
116// doesn't clean up the memory for any temporary variables created.
117var MyCallbackFunc = MyCallback
118
119func Example() {
120 C.CallMyFunction(unsafe.Pointer(&MyCallbackFunc))
121}
122```
123
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100124### Function pointer callbacks
125
126C code can call exported Go functions with their explicit name. But if a C-program wants a function pointer, a gateway function has to be written. This is because we can't take the address of a Go function and give that to C-code since the cgo tool will generate a stub in C that should be called. The following example shows how to integrate with C code wanting a function pointer of a give type.
127
128Place these source files under _$GOPATH/src/ccallbacks/_. Compile and run with:
nathany86c47cc2014-12-10 09:43:20 -0800129
130```console
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100131$ gcc -c clibrary.c
132$ ar cru libclibrary.a clibrary.o
133$ go build ccallbacks
134$ ./ccallbacks
135Go.main(): calling C function with callback to us
136C.some_c_func(): calling callback with arg = 2
137C.callOnMeGo_cgo(): called with arg = 2
138Go.callOnMeGo(): called with arg = 2
139C.some_c_func(): callback responded with 3
140```
141
142**goprog.go**
nathany86c47cc2014-12-10 09:43:20 -0800143
144```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100145package main
146
147/*
148#cgo CFLAGS: -I .
149#cgo LDFLAGS: -L . -lclibrary
150
151#include "clibrary.h"
152
153int callOnMeGo_cgo(int in); // Forward declaration.
154*/
155import "C"
156
157import (
158 "fmt"
159 "unsafe"
160)
161
162//export callOnMeGo
163func callOnMeGo(in int) int {
164 fmt.Printf("Go.callOnMeGo(): called with arg = %d\n", in)
165 return in + 1
166}
167
168func main() {
169 fmt.Printf("Go.main(): calling C function with callback to us\n")
170 C.some_c_func((C.callback_fcn)(unsafe.Pointer(C.callOnMeGo_cgo)))
171}
172```
173
174**cfuncs.go**
nathany86c47cc2014-12-10 09:43:20 -0800175
176```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100177package main
178
179/*
180
181#include <stdio.h>
182
183// The gateway function
184int callOnMeGo_cgo(int in)
185{
186 printf("C.callOnMeGo_cgo(): called with arg = %d\n", in);
187 return callOnMeGo(in);
188}
189*/
190import "C"
191```
192
193**clibrary.h**
194```
195#ifndef CLIBRARY_H
196#define CLIBRARY_H
197typedef int (*callback_fcn)(int);
198void some_c_func(callback_fcn);
199#endif
200```
201
202**clibrary.c**
nathany86c47cc2014-12-10 09:43:20 -0800203
204```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100205#include <stdio.h>
206
207#include "clibrary.h"
208
209void some_c_func(callback_fcn callback)
210{
211 int arg = 2;
212 printf("C.some_c_func(): calling callback with arg = %d\n", arg);
213 int response = callback(2);
214 printf("C.some_c_func(): callback responded with %d\n", response);
215}
216```
217
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100218## Go strings and C strings
219
220Go strings and C strings are different. Go strings are the combination of a length and a pointer to the first character in the string. C strings are just the pointer to the first character, and are terminated by the first instance of the null character, ` '\0' `.
221
222Go provides means to go from one to another in the form of the following three functions:
223 * ` func C.CString(goString string) *C.char `
224 * ` func C.GoString(cString *C.char) string `
225 * ` func C.GoStringN(cString *C.char, length C.int) string `
226
227One important thing to remember is that ` C.CString() ` will allocate a new string of the appropriate length, and return it. That means the C string is not going to be garbage collected and it is up to **you** to free it. A standard way to do this follows.
nathany86c47cc2014-12-10 09:43:20 -0800228
229```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100230// #include <stdlib.h>
231import "C"
232import "unsafe"
233...
234 var cmsg *C.char = C.CString("hi")
235 defer C.free(unsafe.Pointer(cmsg))
236 // do something with the C string
237```
nathany86c47cc2014-12-10 09:43:20 -0800238
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100239Of course, you aren't required to use ` defer ` to call ` C.free() `. You can free the C string whenever you like, but it is your responsibility to make sure it happens.
240
241## Turning C arrays into Go slices
242
243C arrays are typically either null-terminated or have a length kept elsewhere.
244
245Go provides the following function to make a new Go byte slice from a C array:
246 * ` func C.GoBytes(cArray unsafe.Pointer, length C.int) []byte `
247
248To create a Go slice backed by a C array (without copying the original data), one needs to acquire this length at runtime and use ` reflect.SliceHeader `.
249
nathany86c47cc2014-12-10 09:43:20 -0800250```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100251import "C"
252import "unsafe"
253...
254 var theCArray *C.YourType = C.getTheArray()
255 length := int(C.getTheArrayLength())
256 hdr := reflect.SliceHeader{
257 Data: uintptr(unsafe.Pointer(theCArray)),
258 Len: length,
259 Cap: length,
260 }
261 goSlice := *(*[]C.YourType)(unsafe.Pointer(&hdr))
262 // now goSlice is a Go slice backed by the C array
263```
264
265It is important to keep in mind that the Go garbage collector will not interact with this data, and that if it is freed from the C side of things, the behavior of any Go code using the slice is nondeterministic.
266
267Another simpler solution is casting the pointer to a pointer to a very big array and then
268slice it to the length that you want (also remember to set the cap if you're using Go 1.2
269or later), for example (see http://play.golang.org/p/XuC0xqtAIC for a runnable example):
nathany86c47cc2014-12-10 09:43:20 -0800270
271```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100272import "C"
273import "unsafe"
274...
275 var theCArray *C.YourType = C.getTheArray()
276 length := C.getTheArrayLength()
277 slice := (*[1 << 30]C.YourType)(unsafe.Pointer(theCArray))[:length:length]
278```
279
280## Common Pitfalls
281### Struct Alignment Issues
282As Go doesn't support packed struct (e.g., structs where maximum alignment is 1 byte), you can't
283use packed C struct in Go. Even if you program passes compilation, it won't do what you want.
284To use it, you have to read/write the struct as byte array/slice.
285
286Another problem is that some types has lower alignment requirement than their counterpart in Go,
287and if that type happens to be aligned in C but not in Go rules, that struct simply can't be represented
nathany86c47cc2014-12-10 09:43:20 -0800288in Go. An example is this ([issue 7560](https://github.com/golang/go/issues/7560)):
289
290```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100291struct T {
292 uint32_t pad;
293 complex float x;
294};
295```
296Go's complex64 has an alignment of 8-byte, where as C has only 4-byte (because C treats the
297complex float internally as a ` struct { float real; float imag; } `, not a basic type), this T struct simply
298doesn't have a Go representation. For this case, if you control the layout of the struct, move the
299complex float so that it is also aligned to 8-byte is better, and if you're not willing to move it,
300use this form will force it to align to 8-byte (and waste 4-byte):
nathany86c47cc2014-12-10 09:43:20 -0800301
302```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100303struct T {
304 uint32_t pad;
305 __attribute__((align(8))) complex float x;
306};
307```
nathany86c47cc2014-12-10 09:43:20 -0800308
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100309However, if you don't control the struct layout, you will have to define accessor C functions for
310that struct because cgo won't be able to translate that struct into equivalent Go struct.
311
312### ` //export ` and definition in preamble
313If a Go source file uses any ` //export ` directives, then the C code in the comment may only include declarations (` extern int f(); `), not definitions (` int f() { return 1; } ` or ` int n; `).
314Note: you can use ` static inline ` trick to work around this restriction for tiny functions defined
315in the preamble (see above for a complete example).
316
317### Windows
318
319In order to use cgo on Windows, you'll also need to first install a gcc compiler (for instance, mingw-w64) and have gcc.exe (etc.) in your PATH environment variable before compiling with cgo will work.