Golang calls C / C + +, example tutorial


Most people learn or use something, like to see the results of the operation intuitively, then they will have the interest to continue.


There are a lot of online tutorials about golang calling C / C + +. As far as I can see, my personal opinions are quite chaotic and there are many pitfalls. I hope this paper can be more popular and clear to a certain extent.

Now go for short. As always, don’t talk nonsense. Let’s start now.

Go calls C / C + + functions in the following ways:

  • directnestingIn the go file, the most simple and intuitive
  • ImportDynamic library.so or DLLIt’s the safest, but it’s uncomfortable and slow
  • Direct reference to the form of C / C + + files, hierarchical, easy to modify at any time to see the results

ThirdDirect reference to C / C + + filesThat’s what I’m going to talk about.

Environmental support needed

  • Linux has GCC and G + +
  • Windows needs to install MinGW, otherwise there will be such errors when compiling:cannot find -lmingwex
  • Mac reference Linux

1, directly nested in go file

package main
/ * 

void pri(){

int add(int a,int b){
	return a+b;
import "C"  //Don't write this on a new lineimport "fmt"

func main() {
	fmt.Println(C.add(2, 1))

The above code, directly copy run can output results: 3


  • If you want to refer to the content related to C / C + +, write it to the head of go filenotesinside
  • Nested C / C + + code must conform to its syntax, not go
  • import "C"This sentence should be followed closely. Don’t break the line after the annotation, otherwise it will be reported as an error
  • The format of calling c/c++ in go code is:C.xxx()For example, C. add (2, 1)

2. Import dynamic library. So or. DLL

Suppose the project directory is as follows

|  |-lib
|  |  |-libvideo.dll
|  |  |-libvideo.so
|  |-include
|  |  |-video.h
|  |-src
|  |  |-main.go

The header file. H looks like this

#ifndef VIDEO_H
#define VIDEO_H
void exeFFmpegCmd(char* cmd); //Statement

The source file. C looks like this

#include .h>
#include "video.h"

Void exeffmpegcmd (char * CMD) {// implementation
    // ....

To generate the. DLL or. Wing + + library

For example:gcc video.c -fPIC -shared -o libvideo.so

last main.go

Put the dynamic library in a directory you like, or in the current project, as shown in the example above. Re citation

package main


#cgo CFLAGS: -Iinclude

#cgo LDFLAGS: -Llib -llibvideo

#include "video.h"

import "C"

import "fmt"

func main() {
    cmd := C.CString("ffmpeg -i ./xxx/*.png ./xxx/yyy.mp4")

Why is this the safest and the most unpleasant? The reasons are as follows:

  • Dynamic library cracking is very difficult, if your go code leaks, the core dynamic library is not so easy to break
  • The dynamic library will be loaded when it is used, which affects the speed
  • The difficulty of operation is much more troublesome than that of mode one


  • Cflags: - I pathThis statement indicates the path of the header file, and – iinclude indicates the include folder of the root directory of the current project
  • Ldflags: - L path - L NAMEIndicates the path of the dynamic library, – llIB – llibvideo, indicating that it is under lib and its name video
  • If the dynamic library does not exist, it will explodeCan't find a definition or somethingError messages for

3. Direct reference to C / C + + files(key points)

Suppose the project directory is as follows

|  |-util.h
|  |-util.c
|  |-util.go


int sum(int a,int b);


#include "util.h"
int sum(int a,int b){
    return (a+b);


package util

#include "util.c"
import "C"

import "fmt"

func GoSum(a,b int) int {
    s := C.sum(C.int(a),C.int(b))

Call this main.go

package main

func main(){

The third way is thatConcise and clear

Finally, I’d like to add that some famous open source libraries, such asffmpegopencvThese source codes are based on the C / C + + language. In addition, there is a very important point, that is, the running speed!