如何在Nim中封装包含位域的C结构体?
C位域结构体的Nim绑定写法及
packed编译指示疑问 首先给出原C结构体定义:
struct Example { int A; int B; int C : 3; int D : 3; int E : 3; int F : 8; bool G : 1; bool H : 1; };
针对该结构体,以下两种Nim绑定写法哪种正确?
第一种写法:
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
第二种写法:
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
同时需要明确两个问题:
{.packed.}编译指示是否按字节对齐?- 从C导入结构体时是否需要使用该编译指示?
正确的绑定写法
第一种写法是正确的。
Nim中要对应C的位域成员,必须通过{.bitsize: N.}编译指示指定成员占用的位宽,否则Nim会将这些成员当作完整的int32或bool类型处理,完全无法匹配C结构体的位域内存布局,导致数据读写错误。
关于{.packed.}编译指示
{.packed.}的作用是让结构体按字节对齐,即取消编译器默认的内存对齐填充,强制结构体成员紧密排列,不插入任何对齐用的空字节。- 从C导入结构体时,不是必须使用
{.packed.},是否需要添加取决于原C结构体的定义:- 如果原C结构体没有使用
__attribute__((packed))(GCC/Clang)或#pragma pack(MSVC)等打包编译指示,保持默认对齐,那么Nim绑定也不需要加{.packed.}——Nim的默认结构体对齐规则和C一致,能自动匹配内存布局。 - 如果原C结构体明确是打包对齐的,那么Nim绑定必须添加
{.packed.},否则会因为对齐方式不一致导致内存布局不匹配。
- 如果原C结构体没有使用
内容的提问来源于stack exchange,提问作者Joshua Fenner
相关产品推荐
相关产品推荐

