如何将 Go 绑定建模到使用联合的 C 结构?

我目前正在为libfreefare编写Go 包装器。libfreefare 的 API 包含以下函数:


struct mifare_desfire_file_settings {

    uint8_t file_type;

    uint8_t communication_settings;

    uint16_t access_rights;

    union {

    struct {

        uint32_t file_size;

    } standard_file;

    struct {

        int32_t lower_limit;

        int32_t upper_limit;

        int32_t limited_credit_value;

        uint8_t limited_credit_enabled;

    } value_file;

    struct {

        uint32_t record_size;

        uint32_t max_number_of_records;

        uint32_t current_number_of_records;

    } linear_record_file;

    } settings;

};


int      mifare_desfire_get_file_settings (MifareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings);

包装这样一个功能的理想解决方案是什么?如果struct mifare_desfire_file_settings不包含任何联合,我的包装器可能看起来像这样:


type DESFireFileSettings struct {

    // all fields exported, no methods

}


func (t DESFireTag) FileSettings(fileNo byte) (DESFireFileSettings, error)

我应该如何进行?


胡子哥哥
浏览 197回答 1
1回答

撒科打诨

您需要考虑如何更新联合中的字段。显然,你不能让用户在没有验证的情况下这样做。他们可能会进行不一致的更新。考虑做这样的事情:package mifareconst (    MDFTStandarDataFile            = 0x00    MDFTBackupDataFile             = 0x01    MDFTValueFileWithBackup        = 0x02    MDFTLinearRecordFileWithBackup = 0x03    MDFTCyclicRecordFileWithBackup = 0x04)type StandardFile struct {    FileSize uint32}type ValueFile struct {    LowerLimit           int32    UpperLimit           int32    LimitedCreditValue   int32    LimitedCreditEnabled uint8}type LinearRecordFile struct {    Record_size            uint32    MaxNumberOfRecords     uint32    CurrentNumberOfRecords uint32}type DESFireFileSettings struct {    FileType              uint8    CommunicationSettings uint8    AccessRights          uint16    settings              struct {        StandardFile        ValueFile        LinearRecordFile    }}func (fs *DESFireFileSettings) StandardFile() (StandardFile, error) {    // if not valid for FileType, return error    return fs.settings.StandardFile, nil}func (fs *DESFireFileSettings) SetStandardFile(standardFile StandardFile) error {    // if not valid for FileType, return error    fs.settings.StandardFile = standardFile    return nil}func (fs *DESFireFileSettings) ValueFile() (ValueFile, error) {    // if not valid for FileType, return error    return fs.settings.ValueFile, nil}func (fs *DESFireFileSettings) SetValueFile(valueFile ValueFile) error {    // if not valid for FileType, return error    fs.settings.ValueFile = valueFile    return nil}func (fs *DESFireFileSettings) LinearRecordFile() (LinearRecordFile, error) {    // if not valid for FileType, return error    return fs.settings.LinearRecordFile, nil}func (fs *DESFireFileSettings) SetLinearRecordFile(linearRecordFile LinearRecordFile) error {    // if not valid for FileType, return error    fs.settings.LinearRecordFile = linearRecordFile    return nil}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go