Функция C.GoStringN

Функция C.GoStringN преобразует C-строку (указатель на char) в строку Go, используя заданное количество байт. В отличие от C.GoString, она не требует, чтобы C-строка заканчивалась нулевым символом. Первый параметр — указатель на C-строку (тип *C.char), второй — количество байт (тип C.int), которое нужно скопировать. Функция возвращает строку Go, содержащую ровно указанное количество байт из C-строки.

Синтаксис

goC.GoStringN(cstr, n)

Базовый пример

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

gopackage main

/*
#include <stdlib.h>
#include <string.h>
*/
import "C"
import "fmt"

func main() {
  cstr := C.CString("abcde")
  defer C.free(unsafe.Pointer(cstr))

  // Преобразуем первые 3 байта
  res := C.GoStringN(cstr, 3)
  fmt.Println(res)
}

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

go"abc"

Работа с бинарными данными

Поскольку C.GoStringN не требует завершающего нуля, она идеально подходит для обработки бинарных данных или строк, содержащих нулевые байты:

gopackage main

/*
#include <stdlib.h>
#include <string.h>
*/
import "C"
import "fmt"
import "unsafe"

func main() {
  // Создаем C-строку с нулевым байтом внутри
  data := []byte{'a', 'b', 0, 'c', 'd'}
  cstr := (*C.char)(unsafe.Pointer(&data[0]))

  // Преобразуем все 5 байт
  res := C.GoStringN(cstr, C.int(len(data)))
  fmt.Printf("%q (len=%d)\n", res, len(res))
}

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

go"ab\x00cd" (len=5)

Сравнение с C.GoString

Покажем разницу между C.GoStringN и C.GoString на примере строки с нулевым байтом:

gopackage main

/*
#include <stdlib.h>
#include <string.h>
*/
import "C"
import "fmt"
import "unsafe"

func main() {
  data := []byte{'a', 'b', 0, 'c', 'd'}
  cstr := (*C.char)(unsafe.Pointer(&data[0]))

  // C.GoStringN копирует все 5 байт
  res1 := C.GoStringN(cstr, 5)
  fmt.Printf("GoStringN: %q (len=%d)\n", res1, len(res1))

  // C.GoString остановится на нулевом байте
  res2 := C.GoString(cstr)
  fmt.Printf("GoString: %q (len=%d)\n", res2, len(res2))
}

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

go"GoStringN: \"ab\\x00cd\" (len=5)"
"GoString: \"ab\" (len=2)"

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

  • функцию C.GoString,
    которая преобразует C-строку с нулевым завершением в Go-строку
  • функцию C.CString,
    которая создает C-строку из Go-строки
  • функцию C.GoBytes,
    которая преобразует C-массив байт в Go-слайс
  • функцию C.CBytes,
    которая создает C-массив байт из Go-слайса