TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7172 3.3K
📎 Ещё один способ вызывать C из Go без Cgo

Мы недавно писали про purego, который позволяет вызывать C-функции из Go без Cgo. speedboost решает ту же задачу, но заходит с другой стороны.

Авторы заявляют меньший оверхед на вызов по сравнению с purego и более низкоуровневый контроль над тем, как именно происходит взаимодействие с shared-библиотекой.

Как это работает

API состоит из четырёх шагов. Вы загружаете shared-библиотеку, получаете указатель на символ, описываете сигнатуру функции через дескрипторы типов и вызываете её.

Важная особенность — библиотеку можно встроить прямо в Go-бинарник через //go:embed. Это значит, что .so / .dylib / .dll файл не нужно таскать отдельно, он будет внутри вашего приложения.

Вот пример. Допустим, у нас есть функция multiply, написанная на Zig и скомпилированная в shared-библиотеку.
const std = @import("std");

export fn multiply(a: f64, b: f64) callconv(.c) f64 {
return a * b;
}


Go-код, который её вызывает:
//go:embed lib/zig-out/mymath.shared
var sharedLibrary []byte

func main() {
lib, err := sb.LoadLibrary(sharedLibrary)
if err != nil {
panic(err)
}
defer lib.Unload()

mulPtr := lib.GetSymbol("multiply")

cif := sb.SetFuncSignature(
sb.DoubleTypeDescriptor,
sb.DoubleTypeDescriptor,
sb.DoubleTypeDescriptor,
)

var result float64
err = sb.CallFunction(cif, mulPtr, Ptr(&result),
Ptr(new(40.0)), Ptr(new(2.0)))

fmt.Printf("multiply(40.0, 2.0) = %f\n", result) // 80.0
}


Отличия от purego

В purego вы объявляете Go-функцию и привязываете её к C-символу через RegisterLibFunc. Это удобный и высокоуровневый подход. В speedboost всё явнее. Вы сами описываете сигнатуру через дескрипторы типов (DoubleTypeDescriptor и т.п.) и передаёте аргументы как unsafe.Pointer. Больше контроля, но больше ручной работы.

Авторы speedboost утверждают, что их подход даёт меньший оверхед на каждый FFI-вызов. Независимых бенчмарков пока нет, поэтому делать выводы о производительности стоит осторожно.

Кросс-компиляция

Как и purego, speedboost работает с CGO_ENABLED=0. Для сборки под другую платформу достаточно указать GOOS.
GOOS=linux go generate ./...
GOOS=linux CGO_ENABLED=0 go run .


В примере из репозитория shared-библиотека собирается на Zig, который сам по себе хорош для кросс-компиляции. Но speedboost не привязан к Zig — подойдёт любая библиотека с C ABI, собранная на C, Rust или чём угодно ещё.

Стоит ли использовать

Если вам интересен FFI в Go без Cgo и вы хотите попробовать альтернативу purego с более низкоуровневым API, speedboost стоит посмотреть. Особенно если в вашем сценарии критичен оверхед на каждый вызов.

➡️ Репозиторий

📍 Навигация: Вакансии • Задачи • Собесы

🐸 Библиотека Go-разработчика

#GoToProduction
  • 👍 6
  • ❤ 2
  • 👏 1
  • 💯 1
More from @goproglib
  1. Sep 30, 2026🧑‍💻 Эмулятор AWS-сервисов Kumo — это небольшой инструмент на Go для локальной имитации A…
  2. Sep 29, 2026👨‍💻 Библиотека для написания LSP-серверов Написать свой Language Server с нуля на Go сло…
  3. Sep 28, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — 1 true / 0 false 🔥 — 1 true /…
  4. Sep 28, 2026👩‍💻 Что на самом деле происходит внутри Go map? После Go 1.24 обычный map внутри работае…
  5. Sep 26, 2026🔥 В Go 1.27 появился portable SIMD До этого SIMD-оптимизации в Go требовали архитектурног…
  6. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →