我正在尝试将结构从用户空间传递到内核空间。我已经尝试了很多个小时但它不起作用。这是我到目前为止所做的......
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 * pID会这样做(在用户空间中它被定义为pIDs [SIZE])吗?
编辑:
通过上述更改,我收到此错误?错误:在&#39; struct&#39;之前的预期表达式任何想法?
答案 0 :(得分:1)
您的问题中有两种结构变体。
struct mesg1{
int *pIDs;
int niceVal;
};
struct mesg2{
int pIDs[SIZE];
int niceVal;
};
他们是不同的;在mesg1
的情况下,你有指向int数组的指针(在结构之外)。在其他情况下(mesg2
),struct中有int数组。
如果您的SIZE已修复(在模块的API中;用户和内核空间中使用的值相同),则可以使用第二个变体(mesg2
)。
要使用结构的第一个变体(mesg1
),您可以将字段size
添加到结构本身,例如:
struct mesg1{
int pIDs_size;
int *pIDs;
int niceVal;
};
并用*pIDs
指向的整数计数填充它。
PS:并且,从不在结构中间使用具有可变大小数组的结构(也称为VLAIS)。这是GCC编译器对C语言的专有,奇怪,错误和non-documented扩展。根据国际C标准,只有结构的最后一个字段可以是array with variable size(VLA)。这里有一些示例:1 2
PPS:
您可以使用VLA声明结构(如果只有一个具有可变大小的单个数组):
struct mesg2{
int niceVal;
int pIDs[];
};
但是在使用VLA
为这样的结构分配内存时应该小心