Home  >  Article  >  Backend Development  >  Experience sharing: How golang and c language call each other!

Experience sharing: How golang and c language call each other!

藏色散人
藏色散人forward
2021-11-25 14:55:354319browse

This article is provided by the go language tutorial column to introduce how golang and c language call each other. I hope it will be helpful to friends in need!

Mutual calls between go language and c language

Recently due to work reasons, it is necessary to implement mutual calls between go language and c language. Since the Go language and the C language are inextricably linked, the calls between the two can be realized at the language level. Below is a summary of this.

go language calls c language

The following is a brief 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 with "normal" go code, the above code has several "special" features Place:

  • The include word of the c language header file appears in the opening comment

  • The c language function print# is defined in the comment

  • ##Imported a "package" named C

  • The c language function print defined above was called in the main function

First of all, the c language code in the go source file needs to be wrapped with comments, just like the include header file and print function definition above; secondly, the import "C" statement is necessary, and It cannot be separated from the C code above by a blank line and must be closely connected. The "C" here is not a package name, but a concept similar to a namespace, or it can be understood as a pseudo-package. All the syntax elements of the C language are under this pseudo-package; finally, when accessing the c syntax elements, they must be in front of it. Add pseudo-package prefixes, such as C.uint and C.print, C.free, etc. in the above code.

For more detailed usage of calling c language in go, please refer to the interoperation between Go and C language. This article will not go into detail one by one.

In the above example, the C language is embedded in the go code. If the code is larger and more complex, this is obviously very unprofessional. So, can the C language code be separated from the Go code and defined separately? The answer is yes, it can be achieved through shared libraries.

cgo provides the

#cgo indicator to specify which shared libraries the go source code will be linked with after compilation. The example is as follows:

// hello.go
package 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.h
extern void hello();
In hello.go, add

LDFLAGS: -L ./ -lhello after the #cgo indicator, which is used to compile the go code When , specify to search the so library in the current directory and link it.

Therefore, you only need to compile hello.c into a dynamic library, and then compile the go code, and you can call the c language function in the shared library when running 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

and in Compared with calling C source code in go, there are fewer occasions to use go functions in c. Because generally speaking, using high-level languages ​​as a glue to call low-level languages ​​can give full play to their respective characteristics, while using low-level languages ​​to call high-level languages ​​may reduce the performance advantages of low-level languages. In go, you can use "export function name" To export the go function for use by c code, look at a simple example:

// hello.go
package main

import "C"

import "fmt"

// export Go2C
func Go2C() {
    fmt.Println("hello, C")
}
can compile the go code into a shared library for c code to call through the compilation option of

go build. Note that main and main functions must exist when compiling the so library (even if the main function is empty). The compilation instructions are as follows: go build -v -x -buildmode=c-shared -o libhello.so hello.go.

After successful compilation, you only need to introduce the newly generated header file into the c code and link the dynamic library during compilation to realize the call of the go function. The code is as follows:

// hello.c
#include <stdio.h>
#include "libhello.h"

int main()
{
    Go2C();
    return 0;
}
It can be compiled into an executable program through

gcc -o hello -L. -lhello. Note that before running, you must make sure that the shared library that needs to be linked exists in the shared library runtime search path. You can put the so library path in /usr/lib or modify the environment variable LD_LIBRARY_PATH.

Summary

go language can call c language by embedding c code, or by calling shared library functions; as for c language calling go function, you can call it through

go buildCompile go code into a shared library for use by c code. Note that the shared libraries in this article are all dynamic shared libraries. As for static shared libraries, they have not been tested. Those who are interested can implement them.

The above is the detailed content of Experience sharing: How golang and c language call each other!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete