我正在开发一个设备驱动程序模块和相关的用户库来处理ioctl()调用。该库获取相关信息并将其放入一个结构中,该结构被传递到驱动程序模块并在那里解压缩然后处理(我省略了很多步骤,但这是整体想法)。
通过ioctl()传递给struct的一些数据是uint32_t类型。我发现该类型是在stdint.h和linux / types.h中定义的。到目前为止,我一直在使用linux / types.h来定义该值,包括在用户库中。但我理解在用户空间中使用linux / * .h库是不好的形式,所以如果我删除它们而不是使用stdint.h,那么当我的驱动程序模块包含struct定义时,它必须包含stdint.h还
在我看来,linux / types.h的意思是在内核文件中定义类型,所以我不确定这是否意味着使用stdint.h是不好的主意。我还发现,当我在我的驱动程序模块中使用stdint.h时,我得到了关于重新定义的编译错误,即使我用stdint.h替换linux / types.h的所有实例(并把它放在上面)也不会消失包含订单的顶部。)
...洙
感谢。
答案 0 :(得分:4)
- 使用linux / * .h包含在用户空间代码中是不是一个坏主意?
醇>
是的,通常。典型的情况是你应该使用C库头(在这种情况下,stdint.h
和朋友),并通过这些用户空间类型与C库接口,并让库处理与内核交谈通过内核类型。
但你不是典型的情况。在您的情况下,您正在编写驱动程序库。所以你应该使用stdint.h
向用户空间展示一个接口,但在你的内核驱动程序接口时使用linux/*.h
标题。
所以答案是否定的,在你的情况下。
- 在内核空间代码中使用stdint.h是个坏主意吗?
醇>
绝对是肯定的。
答案 1 :(得分:0)
Linux内核中的固定长度整数
Linux内核已经有了固定长度的整数,你可能会感兴趣。在include/asm-generic/int-ll64.h
下的v4.9中:
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
LDD3也有一章关于数据大小:https://static.lwn.net/images/pdf/LDD3/ch11.pdf
LDD3在那里提到最好的printk
策略是强制转换为使用正确的签名强制转换为可能的最大整数:%lld
或%llu
。 %ju
格式核心printk
下的lib/linux/vsprintf.c
似乎不可用。