Implementation of dynamic library of C language called by golang

Time:2022-5-27

Let’s make a dynamic library (. So file – shared object) under Linux, and then use go to use it. The operating system used in this paper is Ubuntu 18.04, with GCC as the compiler.

1. Implement the header file and declare the functions in the file. Here create an add H documents.

?
1
2
3
4
5
6
#ifndef __ADD_H__
#define __ADD_H__
 
char* Add(char* src, int n);
 
#endif

2. Implement the add main function add c

?
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
char* Add(char* src, int n)
{
    char str[20];
    sprintf(str, "%d", n);
    char *result = malloc(strlen(src)+strlen(str)+1);
    strcpy(result, src);
    strcat(result, str);
    return result;
}

3. Use the command to generate the dynamic library. Under Linux, the file name is libadd so

?
1
gcc -fPIC -shared -o lib/libadd.so include/add.c

Libadd. Will be generated in the current directory So file, available under Linux nm – D libadd So view the methods

4. Write a library to test

?
1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include "add.h"
 
int main(int argc, char *argv[])
{
    char* aa = "giter";
    printf("%s\n", Add(aa, 8));
    return 0;
}

Link dynamic library to generate executable file

?
1
gcc include/test.c -L lib/ -ladd -o test
  • -L . Indicates that the current directory is included when searching for library files to link
  • -Ladd means to link the dynamic library libadd So (Note: the default is lib + XXX +. So, and XXX in the middle is the library name)
  • -O test generate executable file test

Error: an error condition in the operation

#Run/ Test, error
./test: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory

The above error occurred. It is possible that the environment variables are not fixed properly, and the dynamic library libadd. Could not be found So, Linux searches for dynamic libraries in some directories (such as / lib, / user / LIB) through the instructions of ldconfig. A simpler way is to use LD_ LIBRARY_ Path environment variable. terms of settlement,

?
1
2
$ LD_LIBRARY_PATH=lib/ ./test
giter8

So far, the dynamic library libadd So is ready, and test is used to verify that it is available. Next, use the functions of the dynamic library in go language.

5. Golang calls C dynamic library

?
1
2
3
4
5
6
7
8
demo1
├── include
│     └── add.c
│     └── add.h
│     └── test.c
├── lib
│     └── libadd.so
└── main.go

main. The code of go is as follows:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
 
/*
//The location of the header file is the current directory relative to the source file, so it is, Write multiple #cgo cflags when header files are in multiple directories:
#cgo CFLAGS: -I./include
//Where to load the dynamic library, location and file name, - Ladd loads libadd So file
#cgo LDFLAGS: -L./lib -ladd -Wl,-rpath,lib
#include "add.h"
*/
import "C"
import "fmt"
 
func main() {
  val := C.Add(C.CString("go"), 2021)
  fmt.Println("run c: ", C.GoString(val))
}

Annotate the code to tell the go compiler where to import header files and load dynamic libraries In this example, * H and * If the go file is in the same directory, #cgo cflags: – I. can not be written.
Cflags: – I and ldflags: – L are relative to the source file main Go location

?
1
2
./demo1
run c:  go2021

Successfully call the add function implemented in C
Some questions are listed below
Import “C” should be next to / **/ Annotation block, if written as

?
1
2
3
4
5
/*
#cgo ...
*/
 
import "C"

The following error message appears

# demo1
./main.go:15:10: could not determine kind of name for C.Add

Import “C” should monopolize one line and try to import other libraries at the same time. For example, import (“C”; “FMT”) will also report the same error as above
The error of not loading the header file is obvious, #include “add. H” will tell you that the file does not exist. If it is not loaded into the correct header file, an error will be reported when calling the C. add() function

# demo1
./main.go:15:10: could not determine kind of name for C.Add

Another key is whether it can be loaded into the dynamic library libadd So, referring to some examples on the Internet, if you change the fifth line to

?
1
cgo LDFLAGS: -L./lib -ladd

There will be no error during compilation and error during execution.

./demo1: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory

But if the environment variable LD is set_ LIBRARY_ Path = / home / vagrant / testgo / lib can also make it run

?
1
LD_LIBRARY_PATH=lib/ ./demo1

This is the end of this article about the implementation of golang calling C language dynamic library. For more information about golang calling C language dynamic library, please search the previous articles of developeppaper or continue to browse the relevant articles below. I hope you will support developeppaper in the future!

Recommended Today

Vue2 technology finishing 3 – Advanced chapter – update completed

3. Advanced chapter preface Links to basic chapters:https://www.cnblogs.com/xiegongzi/p/15782921.html Link to component development:https://www.cnblogs.com/xiegongzi/p/15823605.html 3.1. Custom events of components 3.1.1. Binding custom events There are two implementation methods here: one is to use v-on with vuecomponent$ Emit implementation [PS: this method is a little similar to passing from child to parent]; The other is to use ref […]