【问题标题】:EXPORT_SYMBOL macro is giving conflicting types errorEXPORT_SYMBOL 宏给出冲突类型错误
【发布时间】:2022-01-20 02:07:32
【问题描述】:

我正在尝试将符号导出到内核。但我收到以下错误。我的linux版本是5.4.2,

/home/ram/checkout/drivers/char/i2c_sw_hw_common.c: At top level:
/home/ram/checkout/drivers/char/i2c_sw_hw_common.c:1031:14: error: conflicting types  for ‘sfp_i2c_in32’
 UInt32 sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType)
          ^~~~~~~~~~~~
In file included from /home/ram/checkout/drivers/char/i2c_sw_hw_common.c:3:
/home/ram/checkout/drivers/char/i2c_sw_hw_common.h:123:8: note: previous declaration of ‘sfp_i2c_in32’ was here
 UInt32 sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType);
    ^~~~~~~~~~~~
/home/ram/checkout/drivers/char/i2c_sw_hw_common.c: In function ‘sfp_i2c_in32’:
/home/ram/checkout/drivers/char/i2c_sw_hw_common.c:1035:18: warning: unused variable ‘byte_count’ [-Wunused-variable]
    unsigned int byte_count = 0 ;
              ^~~~~~~~~~
/home/ram/checkout/drivers/char/i2c_sw_hw_common.c: At top level:
/home/ram/checkout/drivers/char/i2c_sw_hw_common.c:1063:29: error: conflicting types for ‘sfp_i2c_in32’
 EXPORT_SYMBOL_NOVERS(sfp_i2c_in32);
                         ^~~~~~~
In file included from /home/ram/checkout/drivers/char/i2c_sw_hw_common.c:3:
/home/ram/checkout/drivers/char/i2c_sw_hw_common.h:123:8: note: previous declaration of ‘sfp_i2c_in32’ was here
 UInt32 sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType);
    ^~~~~~~~~~~~
cc1: some warnings being treated as errors

这是我对这个符号的声明、定义和导出。

i2c_sw_hw_common.c

UInt32 sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType)
{
    // code
}
EXPORT_SYMBOL(sfp_i2c_in32);

i2c_sw_hw_common.h

UInt32 sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType);

【问题讨论】:

  • 虽然错误消息显示声明(在标题中)和定义(在源文件中)的签名相同,但它可能是其中使用的类型的不同含义签名。例如。在包含标头和定义函数之间,它可能类似于源文件中的#define UInt32 int。所以在标头返回值是unsigned int,但在源中它是int
  • 顺便说一句,标题“EXPORT_SYMBOL 宏给出冲突类型错误”是错误的:不是 EXPORT_SYMBOL 导致 primary(第一个)错误.
  • 如果内核已经在<linux/types.h> 中定义了u32(和类似的),我不太确定为什么要重新定义您的类型,例如Uint32?正如 Tsyvarev 提到的,这可能是签名不同的一种方式。尝试更改它,看看错误是否仍然发生。
  • 是的,这就是问题所在。我使用了-save-temps 标志并看到了预处理的输出。在定义中,UInt32 被翻译成unsigned int,但声明仍然是UInt32。需要检查它为什么会发生。但是现在,我已经从这两个地方删除了UInt32,并用unsigned int 替换了它。非常感谢。
  • @Andy J,实际上这段代码是大型驱动程序代码的一部分,我不确定在驱动程序代码中指定用户定义的 typedef UInt32 的原因。

标签: c linux linux-kernel


【解决方案1】:

问题在于使用用户定义的数据类型。我使用的是UInt32,而不是unsigned int,这是用户定义的。

typedef unsigned long UInt32;

这通常不会产生任何问题,只要您在头文件和源文件中都可以看到相同的定义。

但就我而言,在源文件 (.c) 中,UInt32 在预处理完成后被视为宏并扩展为 unsigned int

但在头文件中,UInt32 仍然是用户定义的数据类型。所以编译器抛出了上述错误。

在检查了预处理器阶段的输出后,我知道了这一点(为此使用-save-temps 标志)。

在预处理阶段之后,声明仍然是,

UInt32 sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType);

但是定义改成了,

unsigned int sfp_i2c_in32(char_dev_t *dev,unsigned int I2cDevaddr, int alen, unsigned int offset,unsigned int I2cAddr,int Width, int AccessType)
{
    // code
}

因此,从我的代码中删除了所有用户定义的数据类型,并且只使用了预定义的数据类型。

上述问题的简约示例可以是这样,

// file.h
typedef unsigned long UInt32;

UInt32 f();



// file.c
#include "x.h"

#define UInt32 unsigned int

UInt32 f()
{
    return 0;
}

你会得到的错误,

x.c:6:14: error: conflicting types for ‘f’
 UInt32 f()
        ^
In file included from x.c:2:0:
x.h:3:8: note: previous declaration of ‘f’ was here
 UInt32 f();
        ^

【讨论】:

    猜你喜欢
    • 2017-07-31
    • 2016-02-07
    • 2013-03-25
    • 2014-03-10
    • 2012-10-04
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多