Comprehensive summary: Golang calls C/C++, example tutorial

Most people learn or use something, and like to see the results intuitively, will they be interested in continuing.

If you want to improve your programming skills but don't know where to start, and there is no learning direction and path, then join us and learn together.

C/C++Linux server development/back-end architect [Zero Sound Academy]-Learning Video Tutorial-Tencent Class ke.qq.com

Foreword:

There are many tutorials on Golang calling C/C++ on the Internet. As far as I have seen so far, my personal opinion is rather messy and there are many pitfalls. I hope that this article can be made clearer to a certain extent.

Golang is abbreviated as go below, as always, no nonsense, we will start now.


The implementation methods of calling c/c++ functions in go are:

  • Use directly 嵌套in the go file, the most simple and intuitive
  • The import 动态库 .so 或 dllform is the safest but very uncomfortable and slower
  • Directly quote the form of c/c++ files, with clear levels, easy to modify at any time to see the results

The third 直接引用 c/c++ 文件的形式is the main point I want to introduce.

Environmental support required

  • 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 the go file

package main
/*
// C 标志io头文件,你也可以使用里面提供的函数
#include <stdio.h> 

void pri(){
	printf("hey");
}

int add(int a,int b){
	return a+b;
}
*/
import "C"  // 切勿换行再写这个

import "fmt"

func main() {
	fmt.Println(C.add(2, 1))
}
复制代码

The above code, directly copy and run it will output the result: 3

in conclusion:

  • Whenever you want to reference related to the c / c ++ content, the file is written to the head go 注释inside
  • Nested c/c++ code must conform to its syntax, not the same as go
  • import "C" This sentence should be followed immediately, after the comment, do not wrap, otherwise an error will be reported
  • The format of calling c/c++ in go code is:, C.xxx()for example C.add(2, 1)

2. Import the dynamic library .so or .dll

Suppose the project directory is as follows

|-project
|  |-lib
|  |  |-libvideo.dll
|  |  |-libvideo.so
|  |-include
|  |  |-video.h
|  |-src
|  |  |-main.go
复制代码

The header file.h is as follows

//video.h
#ifndef VIDEO_H
#define VIDEO_H
void exeFFmpegCmd(char* cmd); // 声明
#endif
复制代码

The source file.c is as follows

#include <stdio.h>
#include "video.h"

void exeFFmpegCmd(char* cmd){ // 实现
    // ....
    printf("finish");
}
复制代码

Use gcc or g++ to generate .so library, or generate dll under win

E.g: gcc video.c -fPIC -shared -o libvideo.so

Finally main.go

Put the dynamic library in a directory you like, or in the current project, just like the examples listed above. Requote

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")
   C.exeFFmpegCmd(&cmd)
}
复制代码

First answer why this is the safest and most uncomfortable? The reasons are as follows:

  • The dynamic library is very difficult to crack. If your go code is leaked, the core dynamic library will not be easily compromised.
  • The dynamic library will be loaded when it is used, affecting the speed
  • Operation difficulty is much more troublesome than method one

in conclusion

  • CFLAGS: -I路径 This sentence indicates the path of the header file, -Iinclude indicates the include folder of the current project root directory
  • LDFLAGS: -L路径 -l名字 Specify the path of the dynamic library, -Llib -llibvideo, specify under the lib and its name video
  • If the dynamic library does not exist, 找不到定义之类an error message will be exploded

3. The form of directly referencing c/c++ files (重点)

Suppose the project directory is as follows

|-util
|  |-util.h
|  |-util.c
|  |-util.go
复制代码

util.h

int sum(int a,int b);
复制代码

util.c

#include "util.h"
int sum(int a,int b){
    return (a+b);
}
复制代码

util.go

package util

/*
#include "util.c"
*/
import "C"

import "fmt"

func GoSum(a,b int) {
    s := C.sum(C.int(a),C.int(b))
    fmt.Println(s)
}
复制代码

Call main.go like this

package main

func main(){
    util.GoSum(4,5)
}
复制代码

This is the third way 简洁明了.

Finally, add, need to go to call general c / c ++, mainly using some well-known open source libraries, such as ffmpeg, , opencvand other such source code is based on c / c ++ language, in addition to a very important point, they Is the running speed!


Author: Lin Guanhong _ fingertips under the specter
link: https: //juejin.im/post/6844903553132134414
 

Guess you like

Origin blog.csdn.net/linuxguitu/article/details/109291875