blob: e27f3ba8b14b730c7c11190167372fd12c8b6302 [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) {
Jxck9f1e2a02016-05-09 14:40:47 +090023 printf("%s\n", s);
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110024}
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
Ian Lance Taylor19c29872016-06-02 12:14:05 -070082The following code shows an example of invoking a Go callback from C code. Because of the [pointer passing rules](https://golang.org/cmd/cgo/#hdr-Passing_pointers) Go code can not pass a function value directly to C. Instead it is necessary to use an indirection. This example uses a registry with a mutex, but there are many other ways to map from a value that can be passed to C to a Go function.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110083
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"
Ian Lance Taylor19c29872016-06-02 12:14:05 -070089 "sync"
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110090)
91
92/*
Ian Lance Taylor19c29872016-06-02 12:14:05 -070093extern void go_callback_int(int foo, int p1);
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110094
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.
Ian Lance Taylor19c29872016-06-02 12:14:05 -070099static inline void CallMyFunction(int foo) {
100 go_callback_int(foo, 5);
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100101}
102*/
103import "C"
104
105//export go_callback_int
Ian Lance Taylor19c29872016-06-02 12:14:05 -0700106func go_callback_int(foo C.int, p1 C.int) {
107 fn := lookup(int(foo))
108 fn(p1)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100109}
110
111func MyCallback(x C.int) {
112 fmt.Println("callback with", x)
113}
114
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100115func Example() {
Ian Lance Taylor19c29872016-06-02 12:14:05 -0700116 i := register(MyCallback)
117 C.CallMyFunction(C.int(i))
118 unregister(i)
119}
120
121var mu sync.Mutex
122var index int
123var fns = make(map[int]func(C.int))
124
125func register(fn func(C.int)) int {
126 mu.Lock()
127 defer mu.Unlock()
128 index++
Ian Lance Taylor0a404a12016-06-03 11:03:43 -0700129 for fns[index] != nil {
130 index++
131 }
Ian Lance Taylor19c29872016-06-02 12:14:05 -0700132 fns[index] = fn
133 return index
134}
135
136func lookup(i int) func(C.int) {
137 mu.Lock()
138 defer mu.Unlock()
139 return fns[i]
140}
141
142func unregister(i int) {
143 mu.Lock()
144 defer mu.Unlock()
145 delete(fns, i)
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100146}
147```
148
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100149### Function pointer callbacks
150
151C 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.
152
153Place these source files under _$GOPATH/src/ccallbacks/_. Compile and run with:
nathany86c47cc2014-12-10 09:43:20 -0800154
155```console
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100156$ gcc -c clibrary.c
157$ ar cru libclibrary.a clibrary.o
Erwin Driessens61a22ba2015-09-14 01:05:39 +0200158$ go build
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100159$ ./ccallbacks
160Go.main(): calling C function with callback to us
161C.some_c_func(): calling callback with arg = 2
162C.callOnMeGo_cgo(): called with arg = 2
163Go.callOnMeGo(): called with arg = 2
164C.some_c_func(): callback responded with 3
165```
166
167**goprog.go**
nathany86c47cc2014-12-10 09:43:20 -0800168
169```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100170package main
171
172/*
173#cgo CFLAGS: -I .
174#cgo LDFLAGS: -L . -lclibrary
175
176#include "clibrary.h"
177
178int callOnMeGo_cgo(int in); // Forward declaration.
179*/
180import "C"
181
182import (
183 "fmt"
184 "unsafe"
185)
186
187//export callOnMeGo
188func callOnMeGo(in int) int {
189 fmt.Printf("Go.callOnMeGo(): called with arg = %d\n", in)
190 return in + 1
191}
192
193func main() {
194 fmt.Printf("Go.main(): calling C function with callback to us\n")
195 C.some_c_func((C.callback_fcn)(unsafe.Pointer(C.callOnMeGo_cgo)))
196}
197```
198
199**cfuncs.go**
nathany86c47cc2014-12-10 09:43:20 -0800200
201```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100202package main
203
204/*
205
206#include <stdio.h>
207
208// The gateway function
209int callOnMeGo_cgo(int in)
210{
211 printf("C.callOnMeGo_cgo(): called with arg = %d\n", in);
Jaana Burcu Dogan69b7bf52016-07-29 13:55:27 -0700212 int callOnMeGo(int);
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100213 return callOnMeGo(in);
214}
215*/
216import "C"
217```
218
219**clibrary.h**
220```
221#ifndef CLIBRARY_H
222#define CLIBRARY_H
223typedef int (*callback_fcn)(int);
224void some_c_func(callback_fcn);
225#endif
226```
227
228**clibrary.c**
nathany86c47cc2014-12-10 09:43:20 -0800229
230```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100231#include <stdio.h>
232
233#include "clibrary.h"
234
235void some_c_func(callback_fcn callback)
236{
237 int arg = 2;
238 printf("C.some_c_func(): calling callback with arg = %d\n", arg);
239 int response = callback(2);
240 printf("C.some_c_func(): callback responded with %d\n", response);
241}
242```
243
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100244## Go strings and C strings
245
246Go 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' `.
247
248Go provides means to go from one to another in the form of the following three functions:
249 * ` func C.CString(goString string) *C.char `
250 * ` func C.GoString(cString *C.char) string `
251 * ` func C.GoStringN(cString *C.char, length C.int) string `
252
253One 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 -0800254
255```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100256// #include <stdlib.h>
257import "C"
258import "unsafe"
259...
260 var cmsg *C.char = C.CString("hi")
261 defer C.free(unsafe.Pointer(cmsg))
262 // do something with the C string
263```
nathany86c47cc2014-12-10 09:43:20 -0800264
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100265Of 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.
266
267## Turning C arrays into Go slices
268
269C arrays are typically either null-terminated or have a length kept elsewhere.
270
271Go provides the following function to make a new Go byte slice from a C array:
272 * ` func C.GoBytes(cArray unsafe.Pointer, length C.int) []byte `
273
Ian Lance Tayloreaa92d72015-12-04 14:41:43 -0800274To create a Go slice backed by a C array (without copying the original data), one needs to acquire this length at runtime and use a type conversion to a pointer to a very big array and then slice it to the length that you want (also remember to set the cap if you're using Go 1.2 or later), for example (see http://play.golang.org/p/XuC0xqtAIC for a runnable example):
nathany86c47cc2014-12-10 09:43:20 -0800275
276```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100277import "C"
278import "unsafe"
279...
280 var theCArray *C.YourType = C.getTheArray()
281 length := C.getTheArrayLength()
282 slice := (*[1 << 30]C.YourType)(unsafe.Pointer(theCArray))[:length:length]
283```
284
Ian Lance Tayloreaa92d72015-12-04 14:41:43 -0800285It 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.
286
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100287## Common Pitfalls
288### Struct Alignment Issues
289As Go doesn't support packed struct (e.g., structs where maximum alignment is 1 byte), you can't
290use packed C struct in Go. Even if you program passes compilation, it won't do what you want.
291To use it, you have to read/write the struct as byte array/slice.
292
293Another problem is that some types has lower alignment requirement than their counterpart in Go,
294and 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 -0800295in Go. An example is this ([issue 7560](https://github.com/golang/go/issues/7560)):
296
297```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100298struct T {
299 uint32_t pad;
300 complex float x;
301};
302```
303Go's complex64 has an alignment of 8-byte, where as C has only 4-byte (because C treats the
304complex float internally as a ` struct { float real; float imag; } `, not a basic type), this T struct simply
305doesn't have a Go representation. For this case, if you control the layout of the struct, move the
306complex float so that it is also aligned to 8-byte is better, and if you're not willing to move it,
307use this form will force it to align to 8-byte (and waste 4-byte):
nathany86c47cc2014-12-10 09:43:20 -0800308
309```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100310struct T {
311 uint32_t pad;
312 __attribute__((align(8))) complex float x;
313};
314```
nathany86c47cc2014-12-10 09:43:20 -0800315
Andrew Gerrand5bc444d2014-12-10 11:35:11 +1100316However, if you don't control the struct layout, you will have to define accessor C functions for
317that struct because cgo won't be able to translate that struct into equivalent Go struct.
318
319### ` //export ` and definition in preamble
320If 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; `).
321Note: you can use ` static inline ` trick to work around this restriction for tiny functions defined
322in the preamble (see above for a complete example).
323
324### Windows
325
326In 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.