Правильное использование пустой структуры с CGO

Работа с gssapi.h

struct gss_name_struct;
typedef struct gss_name_struct * gss_name_t;

Я пытаюсь понять, как правильно инициализировать переменную, содержащую это,

var output_name C.gss_name_t = &C.struct_gss_name_struct{}

Но такие функции, как gss_import_name, действуют так, как если бы я передавал им нулевой указатель. . Как правильно инициализировать и использовать эти пустые структуры с CGO?


person user918176    schedule 15.04.2014    source источник


Ответы (1)


Строгая типизация Go затрудняет работу с typedef. Лучший способ сделать ваш Go понятным — написать небольшую функцию-оболочку на C, чтобы построить структуру именно так, как вы хотите. Однако в этом случае go использует массив байтов нулевой длины для пустой структуры C, в чем вы можете убедиться ниже. Вы можете объявить его прямо в go и преобразовать при необходимости.

Поскольку C не является строгим с типами, использование вывода типа часто является самым простым способом присвоить тип, который ожидает Go. Есть также трюк с использованием инструмента cgo, чтобы показать объявления типов, которые вам нужны. Использование go tool cgo -godefs filename.go выведет определения cgo для ваших типов. Однако, как вы видите, эквивалентные типы go могут немного запутаться.

// statement in the original .go file
//var output_name C.gss_name_t = &C.struct_gss_name_struct{}

// output from cgo -godefs
// var output_name *[0]byte = &[0]byte{}

// or more succinctly
output_name := &[0]byte{}

// output_name can be converted directly to a C.gss_name_t
fmt.Printf("%+v\n", output_name)
fmt.Printf("%+v\n", C.gss_name_t(output_name))
person JimB    schedule 15.04.2014
comment
Это действительно работает. Однако следует отметить, что печать [0] байта не очень продуктивна (на самом деле ничего не печатается). Не проблема, у gssapi есть функции C для извлечения строковых представлений. Я просто подумал, что упомяну, чтобы никто не запутался. - person user918176; 16.04.2014