Golang не может получить доступ к C структурам полей в go - PullRequest
0 голосов
/ 10 апреля 2020

У меня проблемы с доступом к c структурам полей в go.

У меня есть файл sdkVersion. go, в котором я определяю структуру (которая отражает то, что библиотека собирается вернуть, и добавляю Функция библиотеки для обработчика в go):

package wrappers

/*
#include <stdint.h>
typedef struct sdk_version_t_
{
    uint32_t build;
    uint8_t major;
    uint8_t minor;
    char name[64];
    char status[32];
} sdk_version_t;
*/
import "C"

type SdkVersion = *C.sdk_version_t

var SdkGetVersion func(SdkHandle) SdkVersion

func addSdkVersionFunctionsToWrapper() {
    addLibFunctionToWrapper("sdk_get_version", &SdkGetVersion)
}

Теперь я хочу получить SDK-версию из общей библиотеки. Поэтому я вызываю это в основной функции:

package main

import "C"
import (
    "fmt"
    "reflect"

    "sdk"
    "wrappers"
)

func main() {
    wrappers.NewWrapper("libsdk.so")
    // creates a handle to the shared library and adds the functions to go

    sdk := sdk.New("Test")
    // calls functions of the shared library and creates a struct which contains amongst other things a handle to the created sdk

    version := wrappers.SdkGetVersion(sdk.Handle)
    // to get the version of the sdk you need to pass the prior created handle
    // returns &{41030 4 1 [52 46 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [114 101 108 101 97 115 101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0]}

    versionVal := *version

    e := reflect.ValueOf(version).Elem()

    fmt.Println(reflect.TypeOf(version))
    // returns *wrappers._Ctype_struct_sdk_version_t_

    for i := 0; i < e.NumField(); i++ {
        varName := e.Type().Field(i).Name
        varType := e.Type().Field(i).Type
        varValue := e.Field(i)

        fmt.Println(varType, varName, varValue)
    }
    // returns
    // wrappers._Ctype_uint build 41030
    // wrappers._Ctype_uchar major 4
    // wrappers._Ctype_uchar minor 1
    // [64]wrappers._Ctype_char name [52 46 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    // [32]wrappers._Ctype_char status [114 101 108 101 97 115 101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    // [2]uint8 _ [0 0]

    fmt.Println(version.build)
    // returns version.build undefined (cannot refer to unexported field or method build)

    fmt.Println(version._build)
    // returns version._build undefined (type *wrappers._Ctype_struct_sdk_version_t_ has no field or method _build)

    fmt.Println(versionVal.build)
    // returns versionVal.build undefined (cannot refer to unexported field or method build)

    fmt.Println(versionVal._build)
    // returns versionVal._build undefined (type wrappers._Ctype_struct_sdk_version_t_ has no field or method _build)
}

Как видите, я могу l oop над полями и печатать их имена и значения, без проблем. Но когда я пытаюсь получить к ним доступ напрямую, я получаю сообщения об ошибках, напечатанные выше. Я довольно плохо знаком с языками программирования более низкого уровня и только начал с go. Кто-нибудь может объяснить, почему я не могу получить доступ к полям структуры c?

Спасибо

...