通过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