mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
update links to issues, syntax highlighting
parent
ad56cb2db2
commit
86c47cc443
50
cgo.md
50
cgo.md
@ -10,9 +10,9 @@ If a Go source file imports ` "C" `, it is using cgo. The Go file will have acce
|
|||||||
|
|
||||||
Note that there must be no blank lines in between the cgo comment and the import statement.
|
Note that there must be no blank lines in between the cgo comment and the import statement.
|
||||||
|
|
||||||
To 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://code.google.com/p/go/issues/detail?id=975)), we will wrap it in the C method "myprint":
|
To 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":
|
||||||
|
|
||||||
```
|
```go
|
||||||
package cgoexample
|
package cgoexample
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -45,7 +45,8 @@ Note: you can't define any C functions in preamble if you're using exports.
|
|||||||
|
|
||||||
For example, there are two files, foo.c and foo.go:
|
For example, there are two files, foo.c and foo.go:
|
||||||
foo.go contains:
|
foo.go contains:
|
||||||
```
|
|
||||||
|
```go
|
||||||
package gocallback
|
package gocallback
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@ -65,8 +66,10 @@ func Example() {
|
|||||||
C.ACFunction()
|
C.ACFunction()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
foo.c contains:
|
foo.c contains:
|
||||||
```
|
|
||||||
|
```go
|
||||||
#include "_cgo_export.h"
|
#include "_cgo_export.h"
|
||||||
void ACFunction() {
|
void ACFunction() {
|
||||||
printf("ACFunction()\n");
|
printf("ACFunction()\n");
|
||||||
@ -78,7 +81,7 @@ void ACFunction() {
|
|||||||
|
|
||||||
The 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.
|
The 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.
|
||||||
|
|
||||||
```
|
```go
|
||||||
package gocallback
|
package gocallback
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -118,14 +121,13 @@ func Example() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Function pointer callbacks
|
### Function pointer callbacks
|
||||||
|
|
||||||
C 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.
|
C 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.
|
||||||
|
|
||||||
Place these source files under _$GOPATH/src/ccallbacks/_. Compile and run with:
|
Place these source files under _$GOPATH/src/ccallbacks/_. Compile and run with:
|
||||||
```
|
|
||||||
|
```console
|
||||||
$ gcc -c clibrary.c
|
$ gcc -c clibrary.c
|
||||||
$ ar cru libclibrary.a clibrary.o
|
$ ar cru libclibrary.a clibrary.o
|
||||||
$ go build ccallbacks
|
$ go build ccallbacks
|
||||||
@ -138,7 +140,8 @@ C.some_c_func(): callback responded with 3
|
|||||||
```
|
```
|
||||||
|
|
||||||
**goprog.go**
|
**goprog.go**
|
||||||
```
|
|
||||||
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -169,7 +172,8 @@ func main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
**cfuncs.go**
|
**cfuncs.go**
|
||||||
```
|
|
||||||
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -196,7 +200,8 @@ void some_c_func(callback_fcn);
|
|||||||
```
|
```
|
||||||
|
|
||||||
**clibrary.c**
|
**clibrary.c**
|
||||||
```
|
|
||||||
|
```go
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "clibrary.h"
|
#include "clibrary.h"
|
||||||
@ -210,11 +215,6 @@ void some_c_func(callback_fcn callback)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Go strings and C strings
|
## Go strings and C strings
|
||||||
|
|
||||||
Go 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' `.
|
Go 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' `.
|
||||||
@ -225,7 +225,8 @@ Go provides means to go from one to another in the form of the following three f
|
|||||||
* ` func C.GoStringN(cString *C.char, length C.int) string `
|
* ` func C.GoStringN(cString *C.char, length C.int) string `
|
||||||
|
|
||||||
One 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.
|
One 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.
|
||||||
```
|
|
||||||
|
```go
|
||||||
// #include <stdlib.h>
|
// #include <stdlib.h>
|
||||||
import "C"
|
import "C"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
@ -234,6 +235,7 @@ import "unsafe"
|
|||||||
defer C.free(unsafe.Pointer(cmsg))
|
defer C.free(unsafe.Pointer(cmsg))
|
||||||
// do something with the C string
|
// do something with the C string
|
||||||
```
|
```
|
||||||
|
|
||||||
Of 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.
|
Of 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.
|
||||||
|
|
||||||
## Turning C arrays into Go slices
|
## Turning C arrays into Go slices
|
||||||
@ -245,7 +247,7 @@ Go provides the following function to make a new Go byte slice from a C array:
|
|||||||
|
|
||||||
To 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 `.
|
To 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 `.
|
||||||
|
|
||||||
```
|
```go
|
||||||
import "C"
|
import "C"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
...
|
...
|
||||||
@ -265,7 +267,8 @@ It is important to keep in mind that the Go garbage collector will not interact
|
|||||||
Another simpler solution is casting the pointer to a pointer to a very big array and then
|
Another simpler solution is casting the pointer 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
|
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):
|
or later), for example (see http://play.golang.org/p/XuC0xqtAIC for a runnable example):
|
||||||
```
|
|
||||||
|
```go
|
||||||
import "C"
|
import "C"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
...
|
...
|
||||||
@ -282,8 +285,9 @@ To use it, you have to read/write the struct as byte array/slice.
|
|||||||
|
|
||||||
Another problem is that some types has lower alignment requirement than their counterpart in Go,
|
Another problem is that some types has lower alignment requirement than their counterpart in Go,
|
||||||
and if that type happens to be aligned in C but not in Go rules, that struct simply can't be represented
|
and if that type happens to be aligned in C but not in Go rules, that struct simply can't be represented
|
||||||
in Go. An example is this (issue 7560 (on Google Code)):
|
in Go. An example is this ([issue 7560](https://github.com/golang/go/issues/7560)):
|
||||||
```
|
|
||||||
|
```go
|
||||||
struct T {
|
struct T {
|
||||||
uint32_t pad;
|
uint32_t pad;
|
||||||
complex float x;
|
complex float x;
|
||||||
@ -294,12 +298,14 @@ complex float internally as a ` struct { float real; float imag; } `, not a basi
|
|||||||
doesn't have a Go representation. For this case, if you control the layout of the struct, move the
|
doesn't have a Go representation. For this case, if you control the layout of the struct, move the
|
||||||
complex float so that it is also aligned to 8-byte is better, and if you're not willing to move it,
|
complex float so that it is also aligned to 8-byte is better, and if you're not willing to move it,
|
||||||
use this form will force it to align to 8-byte (and waste 4-byte):
|
use this form will force it to align to 8-byte (and waste 4-byte):
|
||||||
```
|
|
||||||
|
```go
|
||||||
struct T {
|
struct T {
|
||||||
uint32_t pad;
|
uint32_t pad;
|
||||||
__attribute__((align(8))) complex float x;
|
__attribute__((align(8))) complex float x;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
However, if you don't control the struct layout, you will have to define accessor C functions for
|
However, if you don't control the struct layout, you will have to define accessor C functions for
|
||||||
that struct because cgo won't be able to translate that struct into equivalent Go struct.
|
that struct because cgo won't be able to translate that struct into equivalent Go struct.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user