Most people learn or use something, like to see the results of the operation intuitively, then they will have the interest to continue.
preface:
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:
- direct
nesting
In the go file, the most simple and intuitive - Import
Dynamic library.so or DLL
It’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 + + files
That’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(){
printf("hey");
}
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
Conclusion
- If you want to refer to the content related to C / C + +, write it to the head of go file
notes
inside - 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
|-project
| |-lib
| | |-libvideo.dll
| | |-libvideo.so
| |-include
| | |-video.h
| |-src
| | |-main.go
The header file. H looks like this
//video.h
#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
// ....
printf("finish");
}
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")
C.exeFFmpegCmd(&cmd)
}
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
conclusion
Cflags: - I path
This statement indicates the path of the header file, and – iinclude indicates the include folder of the root directory of the current projectLdflags: - L path - L NAME
Indicates 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 explode
Can't find a definition or something
Error messages for
3. Direct reference to C / C + + files(key points)
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) int {
s := C.sum(C.int(a),C.int(b))
fmt.Println(s)
}
Call this main.go
package main
func main(){
util.GoSum(4,5)
}
The third way is thatConcise and clear
。
Finally, I’d like to add that some famous open source libraries, such asffmpeg
,opencv
These source codes are based on the C / C + + language. In addition, there is a very important point, that is, the running speed!