summaryrefslogtreecommitdiff
path: root/doc/articles/c_go_cgo.html
blob: b37a6ba65b1a6bb967939e527ba1f3fa7a010928 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<!--{
"Title": "C? Go? Cgo!",
"Template": true
}-->

<p>
Cgo lets Go packages call C code. Given a Go source file written with some
special features, cgo outputs Go and C files that can be combined into a
single Go package.
</p>

<p>
To lead with an example, here's a Go package that provides two functions -
<code>Random</code> and <code>Seed</code> - that wrap C's <code>random</code>
and <code>srandom</code> functions.
</p>

{{code "/doc/progs/cgo1.go" `/package rand/` `/END/`}}

<p>
Let's look at what's happening here, starting with the import statement.
</p>

<p>
The <code>rand</code> package imports <code>"C"</code>, but you'll find there's
no such package in the standard Go library. That's because <code>C</code> is a
"pseudo-package", a special name interpreted by cgo as a reference to C's
name space.
</p>

<p>
The <code>rand</code> package contains four references to the <code>C</code>
package: the calls to <code>C.random</code> and <code>C.srandom</code>, the
conversion <code>C.uint(i)</code>, and the <code>import</code> statement.
</p>

<p>
The <code>Random</code> function calls the standard C library's <code>random</code>
function and returns the result.  In C, <code>random</code> returns a value of the
C type <code>long</code>, which cgo represents as the type <code>C.long</code>.
It must be converted to a Go type before it can be used by Go code outside this
package, using an ordinary Go type conversion:
</p>

{{code "/doc/progs/cgo1.go" `/func Random/` `/STOP/`}}

<p>
Here's an equivalent function that uses a temporary variable to illustrate
the type conversion more explicitly:
</p>

{{code "/doc/progs/cgo2.go" `/func Random/` `/STOP/`}}

<p>
The <code>Seed</code> function does the reverse, in a way. It takes a
regular Go <code>int</code>, converts it to the C <code>unsigned int</code>
type, and passes it to the C function <code>srandom</code>.
</p>

{{code "/doc/progs/cgo1.go" `/func Seed/` `/END/`}}

<p>
Note that cgo knows the <code>unsigned int</code> type as <code>C.uint</code>;
see the <a href="/cmd/cgo">cgo documentation</a> for a complete list of
these numeric type names.
</p>

<p>
The one detail of this example we haven't examined yet is the comment
above the <code>import</code> statement.
</p>

{{code "/doc/progs/cgo1.go" `/\/\*/` `/STOP/`}}

<p>
Cgo recognizes this comment.  Any lines starting
with <code>#cgo</code>
followed
by a space character are removed; these become directives for cgo.
The remaining lines are used as a header when compiling the C parts of
the package.  In this case those lines are just a
single <code>#include</code>
statement, but they can be almost any C code.  The <code>#cgo</code>
directives are
used to provide flags for the compiler and linker when building the C
parts of the package.
</p>

<p>
There is a limitation: if your program uses any <code>//export</code>
directives, then the C code in the comment may only include declarations
(<code>extern int f();</code>), not definitions (<code>int f() {
return 1; }</code>).  You can use <code>//export</code> directives to
make Go functions accessible to C code.
</p>

<p>
The <code>#cgo</code> and <code>//export</code> directives are
documented in
the <a href="/cmd/cgo/">cgo documentation</a>.
</p>

<p>
<b>Strings and things</b>
</p>

<p>
Unlike Go, C doesn't have an explicit string type. Strings in C are
represented by a zero-terminated array of chars.
</p>

<p>
Conversion between Go and C strings is done with the
<code>C.CString</code>, <code>C.GoString</code>, and
<code>C.GoStringN</code> functions. These conversions make a copy of the
string data.
</p>

<p>
This next example implements a <code>Print</code> function that writes a
string to standard output using C's <code>fputs</code> function from the
<code>stdio</code> library:
</p>

{{code "/doc/progs/cgo3.go" `/package print/` `/END/`}}

<p>
Memory allocations made by C code are not known to Go's memory manager.
When you create a C string with <code>C.CString</code> (or any C memory
allocation) you must remember to free the memory when you're done with it
by calling <code>C.free</code>.
</p>

<p>
The call to <code>C.CString</code> returns a pointer to the start of the
char array, so before the function exits we convert it to an
<a href="/pkg/unsafe/#Pointer"><code>unsafe.Pointer</code></a> and release
the memory allocation with <code>C.free</code>. A common idiom in cgo programs
is to <a href="/doc/articles/defer_panic_recover.html"><code>defer</code></a>
the free immediately after allocating (especially when the code that follows
is more complex than a single function call), as in this rewrite of
<code>Print</code>:
</p>

{{code "/doc/progs/cgo4.go" `/func Print/` `/END/`}}

<p>
<b>Building cgo packages</b>
</p>

<p>
To build cgo packages, just use <a href="/cmd/go/#hdr-Compile_packages_and_dependencies">"
<code>go build</code>"</a> or
<a href="/cmd/go/#hdr-Compile_and_install_packages_and_dependencies">"<code>go install</code>
"</a> as usual. The go tool recognizes the special <code>"C"</code> import and automatically
uses cgo for those files.
</p>

<p>
<b>More cgo resources</b>
</p>

<p>
The <a href="/cmd/cgo/">cgo command</a> documentation has more detail about
the C pseudo-package and the build process. The <a href="/misc/cgo/">cgo examples</a>
in the Go tree demonstrate more advanced concepts.
</p>

<p>
For a simple, idiomatic example of a cgo-based package, see Russ Cox's <a
href="http://code.google.com/p/gosqlite/source/browse/sqlite/sqlite.go">gosqlite</a>.
Also, the <a href="http://code.google.com/p/go-wiki/wiki/Projects">Go Community Wiki</a>
lists many packages, some of which use cgo.
</p>

<p>
Finally, if you're curious as to how all this works internally, take a look
at the introductory comment of the runtime package's <a href="/src/pkg/runtime/cgocall.c">cgocall.c</a>.
</p>