Подробное резюме: Golang вызывает C/C++, пример руководства

Go C++
Подробное резюме: Golang вызывает C/C++, пример руководства

Автор: Линь Гуаньхун / Призраки под рукой

Самородки: 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++ Кроме того, есть очень важный момент, это скорость работы!

Заканчивать