Автор: Линь Гуаньхун / Призраки под рукой
Самородки: https://juejin.cn/user/1785262612681997
Блог: http://www.cnblogs.com/linguanh/
Гитхаб: https://github.com/af913337456/
Большинство людей что-то изучают или используют, и им нравится интуитивно видеть результаты практических занятий, и им будет интересно продолжать.
Предисловие:
В Интернете есть много руководств по вызову C/C++ на Golang, насколько я видел до сих пор, мое личное мнение таково, что это беспорядочно и есть много ям. Я надеюсь, что эта статья может сделать его более ясным в определенной степени.
Ниже golang упоминается как go , как всегда, не говорите чушь, давайте начнем прямо сейчас.
Реализация go, вызывающая функции c/c++, выглядит следующим образом:
- непосредственный
嵌套
Используйте файлы go, самые простые и интуитивно понятные - Импортировать
动态库 .so 或 dll
Форма самая безопасная, но неприятная и медленная - Непосредственно обращайтесь к форме файлов c/c++, с четкими слоями, легко модифицируемыми и видим результаты в любое время
Третий直接引用 c/c++ 文件的形式
находится в центре внимания моего введения.
Нужна экологическая поддержка
- Linux может иметь gcc и g++
- Винда требует установкиmingw, иначе при компиляции будет такая ошибка:
cannot find -lmingwex
- Справочник по Mac Linux
1, непосредственно вложенный в файл go
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))
}
Приведенный выше код можно вывести, скопировав и запустив напрямую: 3
в заключении:
- Всякий раз, когда вы хотите сослаться на контент, связанный с c/c++, напишите его в заголовке файла go.
注释
в - Вложенный код c/c++ должен соответствовать своему синтаксису, в отличие от go.
-
import "C"
За этим предложением следует следовать сразу после комментария не переносите строку, иначе будет сообщено об ошибке. - Формат вызова c/c++ в коде go следующий:
C.xxx()
, например C.add(2, 1)
2. Импортируйте динамическую библиотеку в виде .so или .dll
Предположим, что каталог проекта выглядит следующим образом
|-project
| |-lib
| | |-libvideo.dll
| | |-libvideo.so
| |-include
| | |-video.h
| |-src
| | |-main.go
Заголовочный файл .h выглядит следующим образом
//video.h
#ifndef VIDEO_H
#define VIDEO_H
void exeFFmpegCmd(char* cmd); // 声明
#endif
Исходный файл .c выглядит следующим образом
#include <stdio.h>
#include "video.h"
void exeFFmpegCmd(char* cmd){ // 实现
// ....
printf("finish");
}
Используйте gcc или g++ для создания библиотеки .so или сгенерируйте dll под win
Например:gcc video.c -fPIC -shared -o libvideo.so
Наконец-то main.go
Поместите динамическую библиотеку в каталог по своему вкусу или в текущий проект, как в примерах, перечисленных выше. реквотировать
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)
}
Сначала ответьте, почему это самое безопасное и самое неприятное? Причины следующие:
- Взлом динамической библиотеки очень сложен.
- Динамические библиотеки будут загружаться при их использовании, что влияет на скорость
- Сложность операции гораздо хлопотнее метода
в заключении
-
CFLAGS: -I路径
Это предложение указывает путь, по которому находится заголовочный файл, а -Iinclude указывает включаемую папку текущего корневого каталога проекта. -
LDFLAGS: -L路径 -l名字
Указать путь к динамической библиотеке, -Llib -llibvideo, указать под lib и ее имя video - Если динамическая библиотека не существует, она взорвется
找不到定义之类
сообщение об ошибке
3. В виде прямой ссылки на файлы c/c++(重点)
Предположим, что каталог проекта выглядит следующим образом
|-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)
}
вызовите main.go вот так
package main
func main(){
util.GoSum(4,5)
}
Третий способ简洁明了
.
Наконец, добавим, что вообще необходимо использовать go для вызова c/c++, в основном используя некоторые известные библиотеки с открытым исходным кодом, такие какffmpeg
,opencv
, и т. д. Эти исходники основаны на языке c/c++ Кроме того, есть очень важный момент, это скорость работы!