【问题标题】:Why is there an incompatible pointer type warning?为什么会出现不兼容的指针类型警告?
【发布时间】:2014-12-28 00:35:20
【问题描述】:

我正在使用内核 3.13.0 编写 Linux 设备驱动程序,但我很困惑为什么会收到此警告。

warning: initialization from incompatible pointer type [enabled by default]
     .read = read_proc,
     ^
warning: (near initialization for ‘proc_fops.read’) [enabled by default]

据我所知,proc 函数的 file_operations 设置与设备函数相同。我可以毫无问题地读取/写入 /dev/MyDevice 并且没有警告。 proc write 函数不会发出警告,只会发出警告。我做错了什么?

/*****************************************************************************/
//DEVICE OPERATIONS
/*****************************************************************************/ 
static ssize_t dev_read(struct file *pfil, char __user *pBuf, size_t
  len, loff_t *p_off)
{
    //Not relevant to this question
}

static ssize_t dev_write(struct file *pfil, const char __user *pBuf,
                         size_t len, loff_t *p_off)
{
    //Not relevant to this question
}

static struct file_operations dev_fops =
{ //None of these cause a warning but the code is identical the proc code below
    .owner = THIS_MODULE,
    .read = dev_read,
    .write = dev_write
};

/*****************************************************************************/
//PROCESS OPERATIONS
/*****************************************************************************/
static int read_proc(struct file *pfil, char __user *pBuf, size_t
              len, loff_t *p_off)
{
    //Not relevant to this question
}

static ssize_t write_proc(struct file *pfil, const char __user *pBuf,
                         size_t len, loff_t *p_off)
{
    //Not relevant to this question
}

struct file_operations proc_fops = 
{
    .owner = THIS_MODULE,
    .write = write_proc,
    .read = read_proc, //This line causes the warning.
};

编辑:所以答案是我是个白痴,因为我没有看到“int”与“ssize_t”。谢谢大家! Codenheim 和 Andrew Medico 几乎同时给出了正确答案,但我选择了 Medico's,因为它对未来的访客来说更加迂腐和明显。

【问题讨论】:

    标签: linux kernel linux-device-driver device-driver


    【解决方案1】:

    read_proc 函数的返回类型(引发警告)与干净编译的函数不匹配。

    static ssize_t dev_read(struct file *pfil, char __user *pBuf, size_t len, loff_t *p_off)
    

    对比

    static int read_proc(struct file *pfil, char __user *pBuf, size_t len, loff_t *p_off)
    

    ssize_tint 的大小可能不同。你的函数的返回类型应该是ssize_t

    【讨论】:

      【解决方案2】:

      在处理文件操作时,只需根据此结构遵循规则

      struct file_operations {
          struct module *owner;
          loff_t (*llseek) (struct file *, loff_t, int);
          ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
          ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
          ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
          ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
          ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
          ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
          int (*iterate) (struct file *, struct dir_context *);
          unsigned int (*poll) (struct file *, struct poll_table_struct *);
          long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
          long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
          int (*mmap) (struct file *, struct vm_area_struct *);
          int (*open) (struct inode *, struct file *);
          int (*flush) (struct file *);
          int (*release) (struct inode *, struct file *);
          int (*fsync) (struct file *, loff_t, loff_t, int datasync);
          int (*aio_fsync) (struct kiocb *, int datasync);
          int (*fasync) (int, struct file *, int);
          int (*lock) (struct file *, int, struct file_lock *);
          ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
          unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
          int (*check_flags)(int);
          int (*flock) (struct file *, int, struct file_lock *);
          ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int);
          ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int);
          int (*setlease)(struct file *, long arg, struct file_lock **);
          long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len);
          int (*show_fdinfo)(struct seq_file *m, struct file *f); };
      

      您可以在 Kernel Documentation Documentation/filesystems/vfs.txt 中找到这个结构,或者您可以使用来自 Kernel Source 的标签 vim -t file_operations 找到它,或者您可以查看头文件 /include/linux/fs.h。

      只是你的错误是你使用 static int 而不是使用 ssize_t 的返回类型。

      【讨论】:

        【解决方案3】:

        函数指针需要一个返回类型为 ssize_t 的函数,但您已将其指定为 int 之一

        你需要一个ssize_t,而不是int

        【讨论】:

        • 也不是这样。不发出警告的函数返回 ssize_t.
        • @AndrewMedico - 这是一个错字。我先读为size_t,但重点还是一样。
        猜你喜欢
        • 2012-07-20
        • 2015-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多