From 60b98d62087d582dafdda68c2af281c5e204fe03 Mon Sep 17 00:00:00 2001 From: Francisco Souza Date: Tue, 13 Mar 2012 09:07:37 +1100 Subject: [PATCH] doc: add C? Go? Cgo! article Originally published on The Go Programming Language Blog, March 17, 2011. http://blog.golang.org/2011/03/c-go-cgo.html Update #2547. R=golang-dev, adg CC=golang-dev https://golang.org/cl/5777054 --- doc/articles/c_go_cgo.html | 159 +++++++++++++++++++++++++++++++++++++ doc/docs.html | 2 +- doc/progs/cgo1.go | 23 ++++++ doc/progs/cgo2.go | 21 +++++ doc/progs/cgo3.go | 17 ++++ doc/progs/cgo4.go | 17 ++++ doc/progs/run | 9 ++- doc/reference.html | 4 +- src/cmd/cgo/doc.go | 2 +- 9 files changed, 249 insertions(+), 5 deletions(-) create mode 100644 doc/articles/c_go_cgo.html create mode 100644 doc/progs/cgo1.go create mode 100644 doc/progs/cgo2.go create mode 100644 doc/progs/cgo3.go create mode 100644 doc/progs/cgo4.go diff --git a/doc/articles/c_go_cgo.html b/doc/articles/c_go_cgo.html new file mode 100644 index 0000000000..5244021972 --- /dev/null +++ b/doc/articles/c_go_cgo.html @@ -0,0 +1,159 @@ + + +

+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. +

+ +

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

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

+Let’s look at what's happening here, starting with the import statement. +

+ +

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

+ +

+The rand package contains four references to the C package: +the calls to C.random and C.srandom, the +conversion C.uint(i), and the import statement. +

+ +

+The Random function calls the libc random function and returns +the result. In C, random returns a value of the C type long, +which cgo represents as the type C.long. 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: +

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

+Here’s an equivalent function that uses a temporary variable to illustrate +the type conversion more explicitly: +

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

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

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

+Note that cgo knows the unsigned int type as C.uint; see the +cgo documentation for a complete list of these +numeric type names. +

+ +

+The one detail of this example we haven't examined yet is the comment +above the import statement. +

+ +{{code "/doc/progs/cgo1.go" `/INCLUDE/` `/STOP/`}} + +

+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 "C", without any intervening blank lines, just like a +documentation comment. +

+ +

+Strings and things +

+ +

+Unlike Go, C doesn’t have an explicit string type. Strings in C are +represented by a zero-terminated array of chars. +

+ +

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

+ +

+This next example implements a Print function that writes a +string to standard output using C's fputs function from the +stdio library: +

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

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

+ +

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

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

+Building cgo packages +

+ +

+To build cgo packages, just use "go build" or +"go install" +as usual. The go tool recognizes the special "C" import and automatically uses +cgo for those files. +

+ +

+More cgo resources +

+ +

+The cgo command documentation has more detail about +the C pseudo-package and the build process. The cgo examples in the Go tree +demonstrate more advanced concepts. +

+ +

+For a simple, idiomatic example of a cgo-based package, see Russ Cox’s gosqlite. +Also, the Go Project Dashboard lists several other +cgo packages. +

+ +

+Finally, if you’re curious as to how all this works internally, take a look +at the introductory comment of the runtime package’s cgocall.c. +

diff --git a/doc/docs.html b/doc/docs.html index 9bd0d62b92..af30dacfe0 100644 --- a/doc/docs.html +++ b/doc/docs.html @@ -126,7 +126,7 @@ Guided tours of Go programs. diff --git a/doc/progs/cgo1.go b/doc/progs/cgo1.go new file mode 100644 index 0000000000..3125cda3d8 --- /dev/null +++ b/doc/progs/cgo1.go @@ -0,0 +1,23 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package rand + +// INCLUDE OMIT + +/* +#include +*/ +import "C" + +// STOP OMIT +func Random() int { + return int(C.random()) +} + +// STOP OMIT +func Seed(i int) { + C.srandom(C.uint(i)) +} + +// END OMIT diff --git a/doc/progs/cgo2.go b/doc/progs/cgo2.go new file mode 100644 index 0000000000..f38473b13e --- /dev/null +++ b/doc/progs/cgo2.go @@ -0,0 +1,21 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package rand2 + +/* +#include +*/ +import "C" + +func Random() int { + var r C.long = C.random() + return int(r) +} + +// STOP OMIT +func Seed(i int) { + C.srandom(C.uint(i)) +} + +// END OMIT diff --git a/doc/progs/cgo3.go b/doc/progs/cgo3.go new file mode 100644 index 0000000000..435fd0402d --- /dev/null +++ b/doc/progs/cgo3.go @@ -0,0 +1,17 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package print + +// #include +// #include +import "C" +import "unsafe" + +func Print(s string) { + cs := C.CString(s) + C.fputs(cs, (*C.FILE)(C.stdout)) + C.free(unsafe.Pointer(cs)) +} + +// END OMIT diff --git a/doc/progs/cgo4.go b/doc/progs/cgo4.go new file mode 100644 index 0000000000..3808d62179 --- /dev/null +++ b/doc/progs/cgo4.go @@ -0,0 +1,17 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package print + +// #include +// #include +import "C" +import "unsafe" + +func Print(s string) { + cs := C.CString(s) + defer C.free(unsafe.Pointer(cs)) + C.fputs(cs, (*C.FILE)(C.stdout)) +} + +// END OMIT diff --git a/doc/progs/run b/doc/progs/run index 9d4669b6c2..8b383e5903 100755 --- a/doc/progs/run +++ b/doc/progs/run @@ -28,7 +28,14 @@ law_of_reflection=" interface2 " -all=$(echo $defer_panic_recover $effective_go $error_handling $law_of_reflection slices go1) +c_go_cgo=" + cgo1 + cgo2 + cgo3 + cgo4 +" + +all=$(echo $defer_panic_recover $effective_go $error_handling $law_of_reflection $c_go_cgo slices go1) for i in $all; do go build $i.go diff --git a/doc/reference.html b/doc/reference.html index b5c0f0b9d5..6a8f9dbc66 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -1,6 +1,6 @@ @@ -61,7 +61,7 @@ Using GDB to debug Go programs.

Articles

    -
  • C? Go? Cgo! - linking against C code with cgo.
  • +
  • C? Go? Cgo! - linking against C code with cgo.
  • Defer, Panic, and Recover
  • Go Slices: usage and internals
  • Godoc: documenting Go code - writing good documentation for godoc.
  • diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go index 2c261b5f45..1bb48f44e9 100644 --- a/src/cmd/cgo/doc.go +++ b/src/cmd/cgo/doc.go @@ -123,6 +123,6 @@ and $GOROOT/misc/cgo/gmp for examples. Cgo does not yet work with gccgo. See "C? Go? Cgo!" for an introduction to using cgo: -http://blog.golang.org/2011/03/c-go-cgo.html +http://golang.org/doc/articles/c_go_cgo.html */ package documentation