The question is if I see a bitfield in a c struct as such:
struct Example
{
int A;
int B;
int C : 3;
int D : 3;
int E : 3;
int F : 8;
bool G : 1;
bool H : 1;
};
Would the correct binding in Nim be as such?
type Example {.packed, importc: "Example", "example.h".} = object
a {.importc: "a".} : int32
b {.importc: "b".} : int32
c {.bitsize: 3, importc: "c".} : int32
d {.bitsize: 3, importc: "d".} : int32
e {.bitsize: 3, importc: "e".} : int32
f {.bitsize: 8, importc: "f".} : int32
g {.bitsize: 1, importc: "g".} : bool
h {.bitsize: 1, importc: "h".} : bool
or as such?
type Example {.importc: "Example", "example.h".} = object
a {.importc: "a".} : int32
b {.importc: "b".} : int32
c {.importc: "c".} : int32
d {.importc: "d".} : int32
e {.importc: "e".} : int32
f {.importc: "f".} : int32
g {.importc: "g".} : bool
h {.importc: "h".} : bool
Does the {.packed.}
pragma align on the byte? Is the {.packed.}
pragma even required here because I am importing from C?
The correctest binding is:
type Example {.importc: "struct Example",header:"example.h".} = object
A: cint
B: cint
C{.bitsize:3.}: cint
D{.bitsize:3.}: cint
E{.bitsize:3.}: cint
F{.bitsize:8.}: cint
G{.bitsize:1.}: bool
H{.bitsize:1.}: bool
note struct Example
because you said it was a C struct. If you intend to compile with nim cpp
you can use the above, importc:"Example"
or just importc
with no argument
and yes, if you know your target machine's ints are 32bits, int32
is much more convenient and is what i would use.
{.packed.}
is not what you want, it is the equivalent of
struct __attribute__((__packed__)) Example {
...
}
and using it results in a struct that is 11 bytes instead of 12
you don't need to individually {.importc.}
each member, unless you want to change its name, i.e.
type Example{.importc:"struct Example",header:"example.h".} = object
a{.importc:"A".}: cint
b{.importc:"B".}: cint
c{.importc:"C",bitsize:3.}: cint
...