Я пишу быстрый клиент для старого сетевого протокола на основе Си.Мне нужно отправить данные структуры через сокет TCP в определенном формате.Для этого требуется импортировать структуру C в Swift, а затем инициализировать ее (попытка создать структуру в Swift не приводит к правильному расположению памяти, когда используются массивы).
Вот пример структуры C, в которой я сделалэто успешно:
#define NAME_LEN 16
struct login_cpacket { /* CP_LOGIN py-struct '!bbxx16s16s16s' #8 */
char type;
char query;
char pad2;
char pad3;
unsigned char name[NAME_LEN];
unsigned char password[NAME_LEN];
unsigned char login[NAME_LEN];
};
К сожалению, этот массив unsigned char импортируется как кортеж, которым трудно манипулировать без использования небезопасных указателей.Вот моя успешная, но грубая реализация, использующая 16-кортеж:
static func make16Tuple(string: String) -> (UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8,UInt8) {
var temp: [UInt8] = []
for _ in 0..<16 {
temp.append(0)
}
for (index,char) in string.utf8.enumerated() {
if index < 15 {
// leaving last position with null
temp[index] = char
}
}
let information = (temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[8],temp[9],temp[10],temp[11],temp[12],temp[13],temp[14],temp[15])
return information
}
// CP_LOGIN 8
static func cpLogin(name: String, password: String, login: String) -> Data {
// ugly hack with 16-element tuple and
// C structure header to get bit boundaries to align
var packet = login_cpacket()
packet.type = 8
packet.query = 0
packet.name = make16Tuple(string: name)
packet.login = make16Tuple(string: login)
packet.password = make16Tuple(string: password)
debugPrint("Sending CP_LOGIN 8 query \(packet.query) name \(name)")
let data = Data(bytes: &packet, count: packet.size)
return data
}
Теперь для плохих новостей: следующая структура, которую мне нужно реализовать, имеет массив из 80 символов.Я могу сделать это грубой силой с 80 кортежами, но я открыт для предложений.Я лично предпочитаю избегать небезопасных указателей.Я хотел бы получить доступ к кортежу в виде массива.
Вот новая структура:
#define MSG_LEN 80
struct mesg_cpacket { /* CP_MESSAGE py-struct "!bBBx80s" #1 */
char type;
char group;
char indiv;
char pad1;
char mesg[MSG_LEN];
};