Pular para o conteúdo

De uma struct do C para um molde

Traduzir uma struct, conferir o layout contra o próprio C, e o #pragma pack.

Quando o formato vem descrito como uma struct do C — num cabeçalho .h, numa especificação antiga —, a tradução é campo a campo. O que muda de uma plataforma para outra é o tamanho de alguns tipos do C, e o alinhamento. A tabela resolve o primeiro; o Arcane.C confere o segundo contra o compilador de verdade.

No CNo moldeCuidado
uint8_t, unsigned charu8
int16_t, shorti16short é 16 bits em toda plataforma comum
int32_t, inti32int é 32 bits em toda plataforma comum
longi64 no Linux/macOS, i32 no Windowso motivo de usar int32_t no C
float / doublef32 / f64
char nome[16]["nome", "char", 16]lido até o primeiro zero
uint8_t hash[32]["hash", "bytes", 32]nunca cortado
__attribute__((packed)), #pragma pack(1)Est.definir(…, ordem, yes)
dataforge
adopt Arcane.Estrutura as Est
adopt Arcane.C as C

// struct Ponto3D { uint8_t marca; float x, y, z; uint16_t cor; };
campos := [["marca", "u8"], ["x", "f32"], ["y", "f32"], ["z", "f32"], ["cor", "u16"]]

molde := Est.definir("Ponto3D", campos, "intel")
assert molde.tamanho is C.estrutura(campos).tamanho()     // vinte, como o compilador
assert molde.deslocamento("x") is 4                       // três bytes de enchimento
assert Est.alinhamento_de(molde) is 4

Se o dado vai para uma função C, o caminho é o `Arcane.C`, que monta a struct na memória que o C lê. Arcane.Estrutura é para quando o dado é um arquivo ou um pacote de rede — e não precisa de biblioteca nativa nenhuma.