2

我正在尝试将结构从用户空间传递到内核空间。我已经尝试了好几个小时,但它不起作用。这是我到目前为止所做的..

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 pIDs[SIZE]。int *pIDs 会这样做吗(在用户空间中它被定义为 pIDs[SIZE])?

编辑:

通过上述更改,我收到此错误?错误:“结构”之前的预期表达有什么想法吗?

4

1 回答 1

1

您的问题中有两种结构变体。

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

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

它们不一样; 如果mesg1你有指向 int 数组的指针(它在结构之外)。在其他情况下(mesg2),结构内有 int 数组。

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

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

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

并用整数计数填充它,由*pIDs.

PS:请不要在结构中间使用带有可变大小数组的结构(又名 VLAIS)。这是 GCC 编译器对 C 语言的专有、奇怪、错误和未记录的扩展。根据国际 C 标准,只有结构的最后一个字段可以是可变大小 (VLA) 的数组。这里有一些例子:1 2

PP:

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

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

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

于 2012-08-26T14:32:38.433 回答