This is a creation in Article, where the information may have evolved or changed.
Recently, because of the work reason, need to implement the Go language and C language of mutual invocation. Because the go language and C language are inextricably related, the call between the two can be achieved through the language level. The following is a summary of this.
Go language calls C language
Here is a short example:
package main// #include <stdio.h>// #include <stdlib.h>/*void print(char *str) { printf("%s\n", str);}*/import "C"import "unsafe"func main() { s := "Hello Cgo" cs := C.CString(s) C.print(cs) C.free(unsafe.pointer(cs))}
Compared to the "normal" go code, the above code has several "special" Places:
- The include typeface for the C language header file appears in the comments that begin with
- The C function print is defined in the note
- Import a "package" named C
- The C-language function of the above definition is called in the main function print
First, the C language code in the go source file needs to be wrapped in comments, like the Include header file above and the print function definition, and then the import "C" statement is required, and it cannot be separated from the above C code with a blank line and must be closely connected. Here the "C" is not a package name, but a similar namespace concept, or can be understood as pseudo-package, C language all the syntax elements are under the pseudo-package, and finally, access to the C syntax element is preceded by a pseudo-package prefix, such as C.uint and the above code, such as C.print, C.free, and so on.
In more detail, the use of C language in go can refer to the interoperability of Go and C language, this article is no longer one by one detailed.
In the example above, the C language is embedded in the go code, which is obviously not "professional" if the amount of code is larger and more complex. So, is it possible to separate the C language code from the Go code and define it separately? The answer is yes, it can be done by sharing the library.
CGO provides an #cgo indicator to specify which shared libraries the go source will link to after compilation. Examples are as follows:
// hello.gopackage main// #cgo LDFLAGS: -L ./ -lhello// #include <stdio.h>// #include <stdlib.h>// #include "hello.h"import "C"func main() { C.hello()}// hello.c#include "hello.h"void hello(){ printf("hello, go\n");}// hello.hextern void hello();
Where in Hello.go, the #cgo indicator is added after the LDFLAGS: -L ./ -lhello function is to compile the Go code, specify in the current directory to find so library and link.
Therefore, simply compile the hello.c into a dynamic library and then compile the go code to invoke the C language function in the shared library when you run the Go code. The instructions are as follows:
gcc -fPIC -o libhello.so hello.c
go build -o hello
./hello
C Language calls go language
Compared to calling C source in go, there are fewer occasions to use the Go function in C. Because in general, the use of high-level language as an adhesive to invoke low-level language can give full play to their own characteristics, and low-level language calls to high-level language is likely to reduce the performance advantage of low-level language, in go, you can use the "Export + function name" To export the Go function for C code, see a simple example
// hello.gopackage mainimport "C"import "fmt"// export Go2Cfunc Go2C() { fmt.Println("hello, C")}
go buildThe Compile option allows you to compile the go code into a shared library for C code calls. Note that the main and main functions must exist when compiling the so library (even if the main function is empty). The compile instructions are as follows: go build -v -x -buildmode=c-shared -o libhello.so hello.go .
After the successful compilation, simply introduce the new generated header file in C code and compile-time link dynamic Library to implement the call of Go function. The code is as follows:
// hello.c#include <stdio.h>#include "libhello.h"int main(){ Go2C(); return 0;}
gcc -o hello -L. -lhelloit can be compiled into an executable program. Note that you must determine the shared library in the shared library runtime lookup path that needs to be linked before you run it, either by putting the so library path to/usr/lib or by modifying the environment variable Ld_library_path.
Summary
The go language can be called C in the form of embedded C code, or it can be implemented by invoking shared library functions, and the C language calls the Go function, which can be made go build available to C code by compiling the go code into a shared library. Note that the shared libraries in this article are dynamic shared libraries, as for the static shared library is not experimental, interested can be realized.