Golang: Экспортируйте поля C, чтобы они были видны извне, с помощью CGo

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

Предположим, у меня есть C-структура, которая выглядит так:

typedef struct {
    uint32_t fizz;
    uint64_t buzz;
} test

А в CGo я оборачиваю C-структуру и создаю новые методы следующим образом:

package test    

type Test C.test

func NewTest() *Test {
    return &Test{1,2}
}

Проблема в том, что вне пакета я не могу получить доступ к полям в C-структуре

package main

import "test"

func main() {
    t := test.NewTest()
    _ = t.fizz // ERROR!!! Unexported field name!!
}

Есть ли простой способ обойти это (кроме создания методов доступа для каждого поля)?


person DSnet    schedule 09.08.2014    source источник
comment
Нет, однако, возможно, вам следует переосмыслить, почему вы хотите это сделать?   -  person OneOfOne    schedule 09.08.2014


Ответы (1)


Да, вы можете экспортировать структуры C. Но вам нужно будет следовать тем же правилам для экспорта структуры C, что и для структуры Golang. http://golang.org/ref/spec#Exported_identifiers

main.go

package main

import "test"

func main() {
    t := test.NewTest()
    println(t.Fizz)
}

тест / test.go

package test

/*
   #include "test.h"
*/
import "C"

type Test C.test

func NewTest() *Test {
    return &Test{Fizz: 1, Buzz: 2}
}

тест/test.h

#include <stdint.h>

typedef struct {
    uint32_t Fizz;   // notice that the first character is upper case
    uint64_t Buzz;
} test;

Если по какой-либо причине вы не можете изменить имена полей в структуре C, вам нужно будет создать новую структуру C, которая соответствует точному макету, но с идентификаторами в верхнем регистре.

person tidwall    schedule 13.08.2014