分配 struct file_operations 字段时从不兼容的指针类型初始化
Initialization from incompatible pointer type when assigning struct file_operations fields
我正在编写一个 Linux 设备驱动器,我很困惑为什么会收到此警告。
error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.write = file_write,
这是我创建的代码,当我使用 make 命令时出现上述错误。我尝试将 ssize_t
更改为 int
但我仍然遇到相同的错误。
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/random.h>
MODULE_LICENSE("NIKS");
static char msg[100]={0};
static short readPos =0;
static int file_open(struct inode * , struct file *);
static int file_release(struct inode * , struct file *);
static ssize_t file_read(struct file *, char *, size_t,loff_t * );
static ssize_t file_write(struct file *, char *, size_t,loff_t * );
static struct file_operations fo =
{
.read = file_read,
.open = file_open,
.write = file_write,
.release = file_release,
};
int init_module(void)
{
int t = register_chrdev(150,"encdev",&fo);
if(t<0)
{
printk("error");
}
else
{
printk("success");
}
return t;
}
void cleanup_module(void)
{
unregister_chrdev(150,"encdev");
}
static int file_open(struct inode *in , struct file *fil)
{
return 0;
}
static ssize_t file_read(struct file *fil, char *buf, size_t len,loff_t *off )
{
short count=0;
printk("here %d",msg[0]!=0);
while(len && (msg[readPos]!=0))
{
printk("read");
put_user(msg[readPos],buf++);
count++;
len--;
readPos++;
}
return count;
}
static ssize_t file_write(struct file *fil, char *buf, size_t len,loff_t *off )
{
short ind = 0;
short count =0;
memset(msg,0,100);
readPos = 0;
int i =0;
char bytes[16];
char rand;
while(i<16)
{
get_random_bytes(&rand, sizeof(rand));
bytes[i]=rand;
++count;
i++;
}
int _len = len+16;
while(_len>0 || count%16){
if(ind<16) msg[ind] = bytes[ind];
else{
msg[ind] = (_len>0?buf[ind-16]:'@')^msg[ind-16];
}
++ind;
--_len;
++count;
}
return count;
}
static int file_release(struct inode *in , struct file *fil)
{
printk("done");
return 0;
}
我是 C 语言的新手,我只是不明白为什么会收到此警告。任何人都可以解释为什么我收到此警告以及如何处理吗?
struct file_operations
的 read
和 write
函数指针的正确类型是:
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
因此,在您的模块中,适当的签名是:
static ssize_t file_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t file_write(struct file *, const char __user *, size_t, loff_t *);
// ...
static ssize_t file_read(struct file *fil, char __user *buf, size_t len,loff_t *off)
{
// ...
static ssize_t file_write(struct file *fil, const char __user *buf, size_t len, loff_t *off)
{
缺少的重要部分是 const
限定符,但同样重要的是要记住,从用户空间传递的任何指针都应该用 __user
注释标记(即使编译器不会如果您忘记了它,请警告您,它仅用作 Sparse).
的静态检查
你在其他语句之后还有几个声明,这在C90中是无效的。编译器会就这些警告你,按照警告将它们移到函数体的顶部。
我正在编写一个 Linux 设备驱动器,我很困惑为什么会收到此警告。
error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.write = file_write,
这是我创建的代码,当我使用 make 命令时出现上述错误。我尝试将 ssize_t
更改为 int
但我仍然遇到相同的错误。
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/random.h>
MODULE_LICENSE("NIKS");
static char msg[100]={0};
static short readPos =0;
static int file_open(struct inode * , struct file *);
static int file_release(struct inode * , struct file *);
static ssize_t file_read(struct file *, char *, size_t,loff_t * );
static ssize_t file_write(struct file *, char *, size_t,loff_t * );
static struct file_operations fo =
{
.read = file_read,
.open = file_open,
.write = file_write,
.release = file_release,
};
int init_module(void)
{
int t = register_chrdev(150,"encdev",&fo);
if(t<0)
{
printk("error");
}
else
{
printk("success");
}
return t;
}
void cleanup_module(void)
{
unregister_chrdev(150,"encdev");
}
static int file_open(struct inode *in , struct file *fil)
{
return 0;
}
static ssize_t file_read(struct file *fil, char *buf, size_t len,loff_t *off )
{
short count=0;
printk("here %d",msg[0]!=0);
while(len && (msg[readPos]!=0))
{
printk("read");
put_user(msg[readPos],buf++);
count++;
len--;
readPos++;
}
return count;
}
static ssize_t file_write(struct file *fil, char *buf, size_t len,loff_t *off )
{
short ind = 0;
short count =0;
memset(msg,0,100);
readPos = 0;
int i =0;
char bytes[16];
char rand;
while(i<16)
{
get_random_bytes(&rand, sizeof(rand));
bytes[i]=rand;
++count;
i++;
}
int _len = len+16;
while(_len>0 || count%16){
if(ind<16) msg[ind] = bytes[ind];
else{
msg[ind] = (_len>0?buf[ind-16]:'@')^msg[ind-16];
}
++ind;
--_len;
++count;
}
return count;
}
static int file_release(struct inode *in , struct file *fil)
{
printk("done");
return 0;
}
我是 C 语言的新手,我只是不明白为什么会收到此警告。任何人都可以解释为什么我收到此警告以及如何处理吗?
struct file_operations
的 read
和 write
函数指针的正确类型是:
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
因此,在您的模块中,适当的签名是:
static ssize_t file_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t file_write(struct file *, const char __user *, size_t, loff_t *);
// ...
static ssize_t file_read(struct file *fil, char __user *buf, size_t len,loff_t *off)
{
// ...
static ssize_t file_write(struct file *fil, const char __user *buf, size_t len, loff_t *off)
{
缺少的重要部分是 const
限定符,但同样重要的是要记住,从用户空间传递的任何指针都应该用 __user
注释标记(即使编译器不会如果您忘记了它,请警告您,它仅用作 Sparse).
你在其他语句之后还有几个声明,这在C90中是无效的。编译器会就这些警告你,按照警告将它们移到函数体的顶部。