c - 结构中的函数指针不起作用?

标签 c struct function-pointers undefined-reference atmelstudio

我有一个适用于 IAR 但不适用于 Atmel Studio 7 的驱动程序和代码。我收到错误消息 ld returned 1 exit statusundefined reference to '_read'(或 _write),当我尝试将函数分配给结构内的指针时。

在我需要使用的驱动中有两个指针定义如下:

#define BMM050_WR_FUNC_PTR \
    s8 (*bus_write)(u8, u8, \
    u8 *, u8)

#define BMM050_RD_FUNC_PTR \
    s8 (*bus_read)(u8, u8, \
    u8 *, u8)re

在文件中,它们有一个定义如下的结构:

struct bmm050_t {
    u8 company_id;/**<mag chip id*/
    u8 dev_addr;/**<mag device address*/

    BMM050_WR_FUNC_PTR;/**< bus write function pointer*/
    BMM050_RD_FUNC_PTR;/**< bus read function pointer*/
    void (*delay_msec)(BMM050_MDELAY_DATA_TYPE);/**< delay function pointer*/

    s8 dig_x1;/**< trim x1 data */
    s8 dig_y1;/**< trim y1 data */

    s8 dig_x2;/**< trim x2 data */
    s8 dig_y2;/**< trim y2 data */

    u16 dig_z1;/**< trim z1 data */
    s16 dig_z2;/**< trim z2 data */
    s16 dig_z3;/**< trim z3 data */
    s16 dig_z4;/**< trim z4 data */

    u8 dig_xy1;/**< trim xy1 data */
    s8 dig_xy2;/**< trim xy2 data */

    u16 dig_xyz1;/**< trim xyz1 data */
};

在我的应用程序中,我尝试这样做:

bmm050.bus_write = i2c_write;
bmm050.bus_read = i2c_read;

我的函数定义为:

int8_t i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

int8_t i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

编辑:我按照要求附上错误代码:

c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/5.3.1/../../../../arm-none-eabi/lib/armv6-m\libc.a(lib_a-writer.o): In function `_write_r':
C:\Users\aba\Documents\Atmel Studio\7.0\Project1\Project1\Debug\writer.c(1,1): error: undefined reference to `_write'
c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/5.3.1/../../../../arm-none-eabi/lib/armv6-m\libc.a(lib_a-readr.o): In function `_read_r':
C:\Users\aba\Documents\Atmel Studio\7.0\Project1\Project1\Debug\readr.c(1,1): error: undefined reference to `_read'
collect2.exe(0,0): error: ld returned 1 exit status

最佳答案

我猜你的 i2c_writei2c_read 函数调用了 printfwriteputcputs 或类似的函数。是的?

您看到的错误是包装器 _write_r_read_r 试图调用底层的 writeread功能,并且无法找到它们。参见,例如 this discussion (sec. 6.4)the newlib C library 中实现这些功能.

当您注释掉 bmm050.bus_write = i2c_writebmm050.bus_read = i2c_read 行时,错误就会消失,因为您的代码中没有其他内容调用 read编写。如果您没有在代码中引用 i2c_read,例如当这些行被注释掉时,链接器可以从编译的目标文件中删除 i2c_read。没有 i2c_read,就不需要 _read_rread,因此您不会遇到链接器错误。

那怎么办?

几个选项,按我尝试的顺序排列。

  1. 如果您有支持契约(Contract),请调用您的电路板支持包 (BSP) 供应商。
  2. 搜索 Atmel Studio 源代码/库,看看它们是否为您的特定硬件提供了 _read_write 实现。如果 Atmel Studio 包含用于您的电路板的 BSP,则可能包含这些功能。 (我自己没有 Atmel Studio,即使我有也可能不会有相同的 BSP,所以我不能告诉你比去哪里看更具体。)
  3. 修改您的i2c_readi2c_write 以便它们直接访问设备的I2C 寄存器。如果您可以从这些函数中消除对 C 库的 I/O 例程的调用,您将不再需要 _read_write
  4. 如果您无法找到现有的实现或消除对实现的需求,请在线查找实现。例如,this blog post (德语)包含 _write 的示例实现。那加上线程中它下面的链接,可能会对您有所帮助(即使您不会说德语)。
  5. 最后,如有必要,滚动您自己的 _read_write,这将对您的特定目标执行一些有意义的输入和输出。我知道那是 I2C,但在某些时候您可能希望它是 UART、LCD、七段显示器、Nixie 或其他东西 — 编写您想要的任何 I/O 例程!请注意,这基本上涉及与 #3 相同类型的工作,但在不同的上下文中。

另见:

  • this answer ,这涉及到不同平台上的类似情况
  • this discussion实现您自己的操作系统(有效地)以便 _write_r 有话可说!

关于c - 结构中的函数指针不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40133112/

相关文章:

c - 解析用户输入的两个值

c - 如何优化我的递归迷宫求解器?

c - 在逗号处拆分输入行

go - 接口(interface)的同义结构字段和方法名称

c++ - 有没有办法在没有 reinterpret_cast 的情况下保存多种类型的函数指针?

c++ - 硬件断点 EXCEPTION_SINGLE_STEP 始终

struct - 如何在Swift 4中引用通用Decodable结构

C++ vector 和结构指针

c++ - 用于安全 operator[] 访问的指向成员数组的静态指针

c - 尝试在变量类型中使用 void 指针调用函数