Instructions for opening a pit
Recently, I have encountered cross-language SDK integration many times when writing client programs or integrating functions with other departments. Although there are many solutions such as rpc, pipelines, files, ios, and unix sockets, the most perfect basic method is to combine the program with SDK (personal opinion, please do not spray if you don’t like it). By the way, I studied various methods and pitfalls in calling the standard C interface in Go. There are a lot of content, and I will update it slowly when I have time.
Inline form
Let's first look at the simplest cgo example
package main //#include <> import "C" func main() { (("Hello World")) }
Output
Hello World
The common puts function in c is called through the "C package" and passed in the c string (equivalent to char *) by converting the string in go. In fact, "C" is not a package, but the go compiler cgo-related functions are enabled through the import "C" statement, so that gcc can also participate in the compilation. This way, by writing the c code closely in the comments above the import "C" statement and using C object calls in subsequent code. Of course, you can also call custom c functions in this way.
package main import "C" /*#include <> void say_hello_with_name(char * name){ printf("hello %s\n", name); } */ import "C" func main() { C.say_hello_with_name(("oscar")) }
Output
hello oscar
External C code
The built-in C code is of course very convenient, but most of the usage scenarios when using Cgo is that I have a C code library that needs to be reused, such as the stl library in C++ or some encapsulated third-party dependencies in Linux C. At these times, some external c files, .h .c .cpp and other .go files need to be mixed. Let’s first look at the simplest example (calling Linux system account authentication).
// int auth(char *user, char *passwd);
// #include <> #include <> #include <> int auth(char *user, char *passwd){ char *obtpwd; struct spwd *spasswd; spasswd = getspnam(user); obtpwd = crypt(passwd, spasswd->sp_pwdp); if(strcmp(spasswd->sp_pwdp, obtpwd) == 0) return 0; else return 1; }
// package main /* #cgo LDFLAGS: -lcrypt #include "" */ import "C" import "fmt" func main() { var username, password string ("Please enter your username and password: ") _, _ = (&username, &password) rst := ((username), (password)) (rst) }
Ensure that the above three files run in the same go project directory go build -o main build project. #cgo LDFLAGS: -lcrypt This line is the compilation parameters for gcc by cgo. The relevant compilation parameters and connection parameters are available. This is explained in the following article. -lcrypt means that you need to connect to the libcrypt library during compilation.
Note that this kind of c go mixed compilation method is not recommended. Cgo supports very poorly for external c code fragment construction. I cannot specify the search path of c code fragments through compilation parameters in cgo (there is no problem with the header file). This means that when the c code fragments called by the project have to be in the project root directory, which is too bad. I personally think that if there are a large number of external libraries that depend on the C language, please compile them separately. The c library is compiled into static or dynamic libraries using gcc. It is better to let go connect at compile time. It is not a hassle to write a makefile to compile step by step. It is also the example above. Let us modify the compilation process slightly.
1. Build a static library
gcc -c -o -lcrypt ar rcs
get
2. Make some changes
package main /* #cgo CFLAGS: -I./ #cgo LDFLAGS: -L. -lauth -lcrypt #include "" */ import "C" import "fmt" func main() { var username, password string ("Please enter your username and password: ") _, _ = (&username, &password) rst := ((username), (password)) (rst) }
The modification here mainly adds the link parameters of the static library
3. Compilation
go build -o main
You can write a simple makefile as follows:
.PHONY : all all: main : gcc -c -o -lcrypt ar rcs main: go build -o main clean: rm -f main
This also makes the process of obtaining products relatively simple and fast
This is the end of this article about how to call C source code in Go. For more information about Go calling C source code, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!