代码之家  ›  专栏  ›  技术社区  ›  MTCoster

在C中传递匿名结构作为参数

  •  4
  • MTCoster  · 技术社区  · 12 年前

    我有以下的c行(为了可读性,添加了回车符-它们不在代码中):

    #define i2c_write(slave_addr, reg_addr, len, *data_ptr)
        twi_master_write(MPU_TWI, {
            .addr = reg_addr,
            .addr_length = 1,
            .buffer = *data_ptr,
            .length = len,
            .chip = slave_addr
        })
    

    哪里 twi_master_write() 声明如下:

    uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet);
    

    twi_packet_t 声明如下:

    typedef struct twi_packet {
        uint8_t addr[3];
        uint32_t addr_length;
        void *buffer;
        uint32_t length;
        uint8_t chip;
    } twi_packet_t;
    

    的参数 twi_write() 都必须是 unsigned char .

    编译时,我收到以下错误:

    expected expression before '{' token
    

    有没有一种正确的方法来做我在这里试图做的事情,或者这是不可能的?

    3 回复  |  直到 12 年前
        1
  •  4
  •   Quentin    12 年前

    我的看法,在一个可比较的样本中。这是一个编译存根 无法正确运行 ,所以不要按原样运行!

    //
    // Cobbling up a compilation stub
    //
    
    #include <stdint.h>
    
    struct Twi;
    typedef struct Twi Twi;
    
    #define MPU_TWI (Twi*)0
    
    typedef struct twi_packet {
        uint8_t addr[3];
        uint32_t addr_length;
        void *buffer;
        uint32_t length;
        uint8_t chip;
    } twi_packet_t;
    
    uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet);
    
    
    //
    // Now for my answer :
    //
    
    #define i2c_write(slave_addr, reg_addr, len, data_ptr) \
        twi_master_write(MPU_TWI, &(twi_packet_t){         \
            .addr = reg_addr,                              \
            .addr_length = 1,                              \
            .buffer = *data_ptr,                           \
            .length = len,                                 \
            .chip = slave_addr                             \
        })
    
    main()
    {
        // Trigger that macro !
        i2c_write(0, 0, 0, (void**)0);
    }
    

    这将安装 复合文字 并将其地址传递给函数。文本的生存期不超过完整调用表达式的生存期。

        2
  •  2
  •   egur    12 年前

    这里有一种更易读、更正确的宏编写方法。 它将在所有情况下工作 if/else 子句和结构是在一个范围内定义的,因此它的名称是本地的,不会污染您的名称空间。

    #define i2c_write(_slave_addr, _reg_addr, _len, _data_ptr)  \
        do {                                                    \
        twi_packet_t temp = {                                   \
            .addr = _reg_addr,                                  \
            .addr_length = 1,                                   \
            .buffer = _data_ptr,                                \
            .length = _len,                                     \
            .chip = _slave_addr };                              \
                                                                \
        twi_master_write(MPU_TWI, &temp);                       \
        } while (0)
    
        3
  •  1
  •   Whoami    12 年前

    如果您提供一套简单的完整代码,这样我们就可以在这里执行并帮助您,那会更好。同时,我认为您不能在宏中使用“*”,因为宏patamers没有被键入。宏所做的只是符号的替换。