РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1590 of 1593 menu

Передача указателей в C

При работе с cgo возникает необходимость передавать указатели на данные из Go в C-функции. Основное правило: Go может передавать указатель на память, выделенную в Go, в C, но при этом Go-рантайм не должен перемещать эту память. Поэтому важно использовать правильные подходы для работы с указателями. В первый параметр передается указатель на данные, во второй - размер данных.

Синтаксис

C.function(&var, C.int(size))

Пример

Рассмотрим базовый пример передачи указателя на Go-переменную в C-функцию:

package main /* #include <stdio.h> void print_int(int *p) { printf("Value: %d\n", *p); } */ import "C" func main() { value := 42 C.print_int(&value) }

Результат выполнения кода:

"Value: 42"

Пример

Передача указателя на слайс через функцию C.CBytes:

package main /* #include <string.h> #include <stdlib.h> void process_data(void *data, int size) { unsigned char *bytes = (unsigned char*)data; for (int i = 0; i < size; i++) { bytes[i] += 1; } } */ import "C" import "unsafe" func main() { data := []byte{1, 2, 3, 4, 5} cData := C.CBytes(unsafe.Pointer(&data[0]), C.int(len(data))) defer C.free(cData) C.process_data(cData, C.int(len(data))) }

Пример

Передача указателя на структуру в C:

package main /* #include <stdlib.h> typedef struct { int x; int y; } Point; void move_point(Point *p, int dx, int dy) { p->x += dx; p->y += dy; } */ import "C" func main() { point := C.Point{x: 10, y: 20} C.move_point(&point, 5, 10) }

Важные ограничения

При передаче указателей из Go в C необходимо помнить о следующих правилах:

package main /* #include <stdlib.h> void modify_string(char *s) { s[0] = 'H'; } */ import "C" import "unsafe" func main() { // Правильно: используем C.CString для выделения памяти в C str := C.CString("hello") defer C.free(unsafe.Pointer(str)) C.modify_string(str) // Неправильно: передача указателя на Go-строку // goStr := "world" // C.modify_string(&goStr) // ОШИБКА! }

Смотрите также

  • функцию C.CString,
    которая создает C-строку из Go-строки
  • функцию C.free,
    которая освобождает память, выделенную в C
  • функцию C.GoBytes,
    которая преобразует C-данные в Go-слайс
  • функцию C.CBytes,
    которая копирует Go-данные в C-память
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить