13

我正在开发一个设备驱动程序模块和相关的用户库来处理ioctl()调用。该库获取相关信息并将其放入一个结构中,该结构被传递到驱动程序模块并在那里解包然后处理(我省略了很多步骤,但这是总体思路)。

ioctl()通过isuint32_t类型通过结构传递的一些数据。我发现该类型是在<stdint.h>AND中定义的<linux/types.h>。到目前为止,我一直在使用<linux/types.h>它来定义该值,包括在用户库中。但是我知道<linux/*.h>在用户空间中使用库是一种不好的形式,所以如果我删除它们并<stdint.h>改用,那么当我的驱动程序模块包含结构定义时,它也必须包含在内<stdint.h>

在我看来,重点<linux/types.h>是在内核文件中定义类型,所以我不确定这是否意味着<stdint.h>在那里使用是个坏主意。我还发现,当尝试使用 编译我的驱动程序模块时<stdint.h>,我会收到关于不会消失的重新定义的编译错误,即使我替换了<linux/types.h>with的所有实例<stdint.h>(并将其放在包含顺序的顶部)。

  1. 在用户空间代码中使用 linux/*.h 包含是一个坏主意吗?
  2. <stdint.h>在内核空间代码中使用是一个坏主意吗?
  3. 如果这两个问题的答案都是肯定的,那么我该如何处理包含的结构uint32_t由用户库和驱动程序模块共享的情况?
4

2 回答 2

6
  1. 在用户空间代码中使用 linux/*.h 包含是一个坏主意吗?

是的,通常。典型的情况是您应该使用 C 库头文件(在这种情况下,stdint.h和朋友),并通过这些用户空间类型与 C 库接口,并让库通过内核类型处理与内核的对话。

不过,您的情况并不典型。在您的情况下,您正在编写驱动程序库。因此,您应该使用 . 向用户空间提供接口stdint.h,但在linux/*.h与内核驱动程序接口时使用标头。

所以在你的情况下,答案是否定的。

  1. 在内核空间代码中使用 stdint.h 是个坏主意吗?

绝对是的。

另见: http: //lwn.net/Articles/113349/

于 2013-01-27T11:27:01.473 回答
0

Linux 内核中的固定长度整数

Linux 内核已经有您可能感兴趣的固定长度整数。在 v4.9 下include/asm-generic/int-ll64.h

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下显示为不可用。printklib/linux/vsprintf.c

于 2017-05-13T07:29:44.877 回答