我目前正在写一个 Go wrapper对于 libfreefare . 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
不包含任何 union ,我的包装器可能看起来像这样:
type DESFireFileSettings struct {
// all fields exported, no methods
}
func (t DESFireTag) FileSettings(fileNo byte) (DESFireFileSettings, error)
我应该如何进行?
最佳答案
您需要考虑如何更新 union 中的字段。显然,您不能让用户在未经验证的情况下这样做。他们可以进行不一致的更新。考虑做这样的事情:
package mifare
const (
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
}
关于c - 如何将 Go 绑定(bind)建模为使用 union 的 C 结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22888001/