通过IOCTL将结构传递给设备驱动程序 [英] Passing struct to device driver through IOCTL

查看:518
本文介绍了通过IOCTL将结构传递给设备驱动程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将结构从用户空间传递到内核空间.我已经尝试了好几个小时,却无法正常工作.这是我到目前为止所做的..

I am trying to pass a struct from user space to kernel space. I had been trying for many hours and it isn't working. Here is what I have done so far..

int device_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg){

int ret, SIZE;


switch(cmd){

    case PASS_STRUCT_ARRAY_SIZE:

        SIZE = (int *)arg;
        if(ret < 0){
            printk("Error in PASS_STRUCT_ARRAY_SIZE\n");
            return -1;  
        }
        printk("Struct Array Size : %d\n",SIZE);
        break;

    case PASS_STRUCT:


        struct mesg{
            int pIDs[SIZE];
            int niceVal;
        };

        struct mesg data;

        ret = copy_from_user(&data, arg, sizeof(*data));
        if(ret < 0){
            printk("PASS_STRUCT\n");
            return -1;  
        }

        printk("Message PASS_STRUCT : %d\n",data.niceVal);
        break;

    default :
        return -ENOTTY;
}

return 0;
  }

我很难定义结构.定义它的正确方法是什么?我想拥有int pID [SIZE]. int * pID是否会这样做(在用户空间中它的定义类似于pIDs [SIZE])?

I have trouble defining the struct. What is the correct way to define it? I want to have int pIDs[SIZE]. Will int *pIDs do it(in user space it is defined like pIDs[SIZE])?

通过上述更改,我得到此错误吗?错误:构造"任何构想之前的预期表达?

With the above change I get this error? error: expected expression before 'struct' any ideas?

推荐答案

问题中有两种结构变体.

There are two variants of the structure in your question.

 struct mesg1{
  int *pIDs;
  int niceVal;
 };

 struct mesg2{
  int pIDs[SIZE];
  int niceVal;
 };

它们是不同的;在mesg1的情况下,您具有指向int数组的指针(位于结构外部).在其他情况下(mesg2),该结构内部有一个int数组.

They are different; in case of mesg1 you has pointer to int array (which is outside the struct). In other case (mesg2) there is int array inside the struct.

如果SIZE是固定的(在模块的API中;在用户空间和内核空间中使用的值相同),则可以使用第二个变量(mesg2).

If your SIZE is fixed (in API of your module; the same value used in user- and kernel- space), you can use second variant (mesg2).

要使用结构的第一个变体(mesg1),可以在结构本身中添加字段size,例如:

To use first variant of structure (mesg1) you may add field size to the structure itself, like:

 struct mesg1{
  int pIDs_size;
  int *pIDs;
  int niceVal;
 };

,并用*pIDs指向的整数计数填充它.

and fill it with count of ints, pointed by *pIDs.

PS:而且,请从不使用结构中间带有可变大小数组的结构(又名VLAIS).这是专有的,怪异的,有问题的,并且是未记录的对C语言的扩展 GCC编译器.根据国际C,只有结构的最后一个字段可以是大小可变的数组(VLA)标准.这里的一些示例: 1 2

PS: And please, never use structures with variable-sized arrays in the middle of the struct (aka VLAIS). This is proprietary, wierd, buggy and non-documented extension to C language by GCC compiler. Only last field of struct can be array with variable size (VLA) according to international C standard. Some examples here: 1 2

PPS:

您可以使用VLA声明您的结构(如果只有一个具有可变大小的数组):

You can declare you struct with VLA (if there is only single array with variable size):

 struct mesg2{
  int niceVal;
  int pIDs[];
 };

但是在使用VLA为此类结构分配内存时要小心

but you should be careful when allocating memory for such struct with VLA

这篇关于通过IOCTL将结构传递给设备驱动程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆