Use C language code instances in Golang

  • 2020-05-07 19:53:07
  • OfStack

cgo makes the C code available in Golang.

Hello World

For a more intuitive understanding, let's take a look at a simple example to create the file main.go:


package main
 
/*
#include <stdio.h>
 
void sayHi() {
    printf("Hi");
}
*/
import "C"
 
func main() {
    C.sayHi()
}

Execution procedure:

go run main.go

The program executes and outputs hi (see $GOROOT/misc/cgo for more examples).

Preparation under Windows

If you want to use cgo on Windows, you need to install the gcc compiler, and here I'm using mingw-w64.

sets the compile and link flag

We use import "C" to import a pseudo-package (pseudo-package) through which we use C code. Before import "C", comments that follow import "C" can include:

Compiler and linker flags
2. C code

We can set the compiler and linker flags with the #cgo directive, for example:


// #cgo CFLAGS: -DPNG_DEBUG=1
// #cgo amd64 386 CFLAGS: -DX86=1
// #cgo LDFLAGS: -lpng
// #include <png.h>
import "C"

Attached to mention 1 point, these instructions can be included in the build constraint (build constraint), details see: http: / / golang org pkg/go build / # hdr - Build_Constraints.

Common #cgo instructions are:

1. The CPPFLAGS, CFLAGS instructions are used to compile the C files in the current package (any.c,.s,.S files)
2. The CPPFLAGS, CXXFLAGS instructions are used to compile C++ files in the current package (any.cpp,.cc,.cxx files)
3. The LDFLAGS directive is used to specify the linker flag
4. The pkg-config directive is used to obtain compiler and linker flags through the pkg-config tool (e.g. #cgo pkg-config: png cairo)

Golang references C

Points needing attention on the structure:

1. If the domain name of the C structure is the keyword of Golang, you need to add _ before the domain name when accessing it. For example, if C has a struct variable x, and the corresponding struct has a domain type, then in Golang you need to access the type domain through x._type
2. The bit fields and unaligned data of the structure will be ignored if they cannot be represented in Golang
3. Fields of type C cannot be used in Golang structures

The standard C numerical type corresponds to:

1.C.char
2.C.schar (signed char)
3.C.uchar (unsigned char)
4.C.short
5.C.ushort (unsigned short)
6.C.int
7.C.uint (unsigned int)
8.C.long
9.C.ulong (unsigned long)
10.C.longlong (long long)
11.C.ulonglong (unsigned long long)
12.C.float
13.C.double

Any C function (including void) can return 1 return value and errno variable C (as an error) :


n, err := C.sqrt(-1)
_, err := C.voidFunc()

Direct calls to C function Pointers are not currently supported.

There are 1 special functions that can be used to convert between C type and Golang type (by way of data copy). The pseudo-definition is as follows:


// Golang String to C string
// C The string is used malloc Assigned, therefore, the caller of this function
// You need to call C.free To free up memory
func C.CString(string) *C.char
 
// conversion C String to a Golang string
func C.GoString(*C.char) string
 
// conversion 1 Set the length of the C String to a Golang string
func C.GoStringN(*C.char, C.int) string
 
// conversion 1 block C Memory area to Golang To an array of bytes
func C.GoBytes(unsafe.Pointer, C.int) []byte

Other points to note for :

1. void* in C corresponds to unsafe.Pointer
2. Structure, union, enumerated types (not variables) in C language need to be prefixed with struct_, union_, enum_ in Golang. Since there is no such data type as union in Golang, the union of C is represented as a byte array in Golang
3. Types equivalent to C cannot be exported


Related articles: