1
0
mirror of https://github.com/golang/go synced 2024-11-25 15:37:56 -07:00
go/doc/articles/c_go_cgo.html
2012-03-19 22:54:06 +08:00

161 lines
5.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--{
"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>
Lets 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>
Heres 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 and uses it as a header when compiling the C
parts of the package. In this case it is just a simple include statement,
but it can be any valid C code. The comment must be immediately before the
line that imports <code>"C"</code>, without any intervening blank lines,
just like a documentation comment.
</p>
<p>
<b>Strings and things</b>
</p>
<p>
Unlike Go, C doesnt 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 youre 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/#Compile_packages_and_dependencies">"
<code>go build</code>"</a> or
<a href="/cmd/go/#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 Coxs <a
href="http://code.google.com/p/gosqlite/source/browse/sqlite/sqlite.go">gosqlite</a>.
Also, the Go Project Dashboard lists <a
href="https://godashboard.appspot.com/project?tag=cgo">several other
cgo packages</a>.
</p>
<p>
Finally, if youre curious as to how all this works internally, take a look
at the introductory comment of the runtime packages <a href="/src/pkg/runtime/cgocall.c">cgocall.c</a>.
</p>