Преамбула cgo
Преамбула cgo - это блок специальных комментариев, который располагается непосредственно перед импортом пакета "C". В преамбуле указываются директивы для компилятора C, флаги компиляции и линковки, а также объявления C-функций, которые будут доступны из Go-кода. Преамбула позволяет настраивать процесс сборки и интегрировать C-код в Go-программу.
Синтаксис
// #include <stdio.h>
// #include <stdlib.h>
// #cgo CFLAGS: -O2
// #cgo LDFLAGS: -lm
import "C"
Преамбула состоит из строк, начинающихся с //, которые следуют сразу за ключевым словом package. Каждая строка преамбулы интерпретируется как директива для C-компилятора.
Пример
Давайте рассмотрим простой пример использования преамбулы для подключения заголовочного файла и объявления C-функции:
package main
// #include <stdio.h>
// #include <stdlib.h>
//
// void print_message(const char* msg) {
// printf("C says: %s\n", msg);
// }
import "C"
import "unsafe"
func main() {
msg := C.CString("Hello from Go!")
C.print_message(msg)
C.free(unsafe.Pointer(msg))
}
Результат выполнения кода:
"C says: Hello from Go!"
Пример
В следующем примере показано использование директив #cgo для указания флагов компиляции в зависимости от операционной системы:
package main
// #cgo windows CFLAGS: -DWINDOWS
// #cgo linux CFLAGS: -DLINUX
// #cgo darwin CFLAGS: -DMACOS
// #include <stdlib.h>
//
// int get_os_type() {
// #ifdef WINDOWS
// return 1;
// #elif LINUX
// return 2;
// #elif MACOS
// return 3;
// #else
// return 0;
// #endif
// }
import "C"
import "fmt"
func main() {
osType := C.get_os_type()
switch osType {
case 1:
fmt.Println("Running on Windows")
case 2:
fmt.Println("Running on Linux")
case 3:
fmt.Println("Running on macOS")
default:
fmt.Println("Unknown operating system")
}
}
Результат выполнения кода:
"Running on Linux"
Пример
В этом примере показано использование преамбулы для подключения внешней библиотеки с помощью pkg-config:
package main
// #cgo pkg-config: glib-2.0
// #include <glib.h>
//
// char* get_version() {
// return g_strdup(glib_check_version(NULL, NULL, NULL));
// }
import "C"
import (
"fmt"
"unsafe"
)
func main() {
version := C.get_version()
fmt.Printf("GLib version: %s\n", C.GoString(version))
C.free(unsafe.Pointer(version))
}
Результат выполнения кода:
"GLib version: 2.70.0"
Смотрите также
-
директиву
#cgo CFLAGS,
которая задает флаги для C-компилятора -
директиву
#cgo LDFLAGS,
которая задает флаги для линковщика -
директиву
#cgo pkg-config,
которая подключает библиотеки через pkg-config -
функцию
import "C",
которая подключает C-код в Go-программу