After decades of development in the C language, a wide variety of ready-made libraries are already plentiful. With CGO, you can use the C language code in the go language to make the most of the existing "wheels".
All the code in this document is debugged in the following environment:
- Windows 8.1 64-bit
- Go 1.3.3 64-bit
- GCC 4.8.1 64-bit
To use CGO, import the C "package":
Import "C"
Above this line of code to
Close toMeans
ContinuousThe comments of several lines, and write C code in these comments. For example:
/*int PlusOne (int n) {return n + 1;} */import "C"
We know that if you want to reference a symbol in a package, you need to use the "package name. Symbol Name" method, C "Package" is also the case, for example: C.int, C.getwindowlongptr.
The following is a method of using C language variables, functions, structs, unions, callback functions, and dynamic link libraries (library,dll).
- Variable
- Function
- Structural body
- Complex
- callback function
- Dll
1. Variables
The use of C variables is simple, for example, to use int, as long as the go code to write C.int.
Package Mainimport ("FMT") import "C" Func Main () {var n c.intn = 5fmt. PRINTLN (n)//5var M1 int//go does not think C.int is the same type as int, Int32, etc.//so must be converted M1 = Int (n + 3) fmt. PRINTLN (M1)//8var m2 int32m2 = int32 (n +) fmt. Println (m2)//25}
2. Functions
It is not difficult to invoke the C function in go.
Package Mainimport ("FMT")/*int plusone (int n) {return n + 1;} */import "C" Func Main () {var n int = 10var m int = Int (C.plusone (C.int (n)))//type to convert FMT. Println (m) //11}
3. Structural body
Package Mainimport ("FMT")/*typedef struct _point{double x;double y; Point;*/import "C" Func Main () {var p c.pointp.x = 9.45p.y = 23.12fmt. PRINTLN (p)//{9.45 23.12}}
4. Consortium
The use of C's union in Go is a rare and strange thing, and a little cumbersome, because go treats the Union of C as a byte array. For example, the following consortium Large_integer is considered [8]byte.
typedef long LONG;TYPEDEF unsigned long dword;typedef long long longlong;typedef union _large_integer { struct { D WORD LowPart; LONG highpart; }; struct { DWORD lowpart; LONG Highpart; } u; Longlong QuadPart;} Large_integer, *plarge_integer;
So, if a C function has a parameter of type Large_integer, we can give it a [8]byte type argument, and vice versa.
Package Mainimport ("FMT")/*typedef long long;typedef unsigned long dword;typedef long long longlong;typedef Union _large_ INTEGER { struct { DWORD lowpart; LONG highpart; }; struct { DWORD lowpart; LONG Highpart; } u; Longlong QuadPart;} Large_integer, *plarge_integer;void Show (Large_integer li) {li.u.lowpart = 1;li.u.highpart = 4;} */import "C" Func Main () {var li c.large_integer//equivalent to: Var li [8]bytevar b [8]byte = Li //correct, because [8]byte and C.large_integ Er the same c.show (b) //parameter type Large_integer, can receive [8]byteli[0] = 75fmt. Println (LI)//[0 0 0 0 0 0 0]li[4] = 23Test (LI)//parameter type [8]byte, can receive C.large_integer}func Test (b [8]byte) {fmt. Println (b)}
5. Callback function
Some parameters of the C function are callback functions, for example:
typedef uint_ptr (__stdcall* girl_proc) (int); typedef uint_ptr (__cdecl* girl_proc_cdecl) (int); Uint_ptr Func1 (int n, Girl_proc gp) {if (GP = = NULL) {return 0;} Return (*GP) (n);} Uint_ptr Func2 (int n, girl_proc_cdecl gp) {if (GP = = NULL) {return 0;} Return (*GP) (n);}
The Syscall package has the following two functions:
Syscall. Newcallback
Syacall. Newcallbackcdecl
Where the first function receives a go function (the return value of the GO function must be only one, and the type is uintptr), and generates a C function that __stdcall the calling convention, and returns the address of the generated function as a uintptr; the second function is similar in effect. But the calling convention for the generated function is __cdecl.
A notable problem is that the pointer to the function of C is considered *[0]byte in go, so it is necessary to convert it. Here is a demonstration of the use of __stdcall calling convention functions, __cdecl similar.
Package Mainimport ("FMT" "syscall" "unsafe")/* #define Win32_lean_and_mean#include <windows.h>typedef uint_ptr ( __stdcall* girl_proc) (int); typedef uint_ptr (__cdecl* girl_proc_cdecl) (int); Uint_ptr Func1 (int n, Girl_proc gp) {if (GP = = NULL) {return 0;} Return (*GP) (n);} Uint_ptr Func2 (int n, girl_proc_cdecl gp) {if (GP = = NULL) {return 0;} Return (*GP) (n);} */import "C" Func Girlproc (n int32) uintptr {return UIntPtr (n + +)}func Main () {gp: = Syscall. Newcallback (Girlproc) fmt. PRINTLN (GP) GOP: = (*[0]byte) (unsafe. Pointer (GP)) var t c.uint_ptr = c.func1 (c.int), GOP) FMT. PRINTLN (t)//126}
6. dll
Write again later.
[Go Language]cgo usage Demo