为什么定义缓冲区的缓冲区长度会导致该类的函数成员失去函数指针成员变量的值?

问题描述

我正在使用GNU AVR GCC版本5.4.0和Atmelstudio 7.0.2397,但存在以下问题。


问题描述

在下图中,您可以看到直到第13行,程序已将函数usart_send的地址存储到transmitter对象{{的成员}的变量SimpleClass中。 1}}。

enter image description here

sc函数的原型为transmitter ,而void (*transmitter)(uint8_t * txbuff,uint8_t len);函数原型的定义为usart_send

现在,当我进入void usart_send(uint8_t *,uint8_t);函数时,请注意,在类的对象的成员函数内部,foo的地址现在为0。

enter image description here

类似地,在函数transmitter中,其值仍为0。因此,我无法调用所需的函数。这就是反汇编显示内容,我的MCU也是如此。

enter image description here


此问题的原因

所以我有以下用于flush代码

SimpleClass.h

请注意,使用#pragma once typedef unsigned char uint8_t; #ifndef rxBufferLen #define rxBufferLen 30 #endif #ifndef txBufferLen #define txBufferLen 30 #endif class SimpleClass{ uint8_t rxbuffer[rxBufferLen]; ///< receiver buffer uint8_t txBuffer[txBufferLen]; ///< transmitter buffer uint8_t rxbuff_index,///< rxbuffer index. Indicates where to put new data txbuff_index; ///< txBuffer index. Indicates where to put new data public: void (*transmitter)(uint8_t * txbuff,uint8_t len); void pushtx(uint8_t byte); void pushrx(uint8_t byte); void flush(); void foo(); }; 定义了txBufferrxBuffer的长度。在define中,我有以下代码

incfile1.h

在这里,我重新定义了#pragma once #define rxBufferLen 50 #define txBufferLen 50 #include <avr/io.h> #include "simpleClass.h" #define TIMER0_CLOCK_PRESCALAR (3) #define TIMER0_CLOCK_COUNT (0xff - 50) void usart_init(); void timer0_init(); void serial_send_ln(const char *); void usart_send(uint8_t *,uint8_t); void usart_send_ln(uint32_t num); rxBufferLen。这种定义的定义会导致上述问题。如果我删除这两行,则此代码可以正常工作。


问题

因此,您可以看到,通过为类内部的缓冲区定义缓冲区长度,会导致其成员函数失去该类的函数指针(它是成员变量)的值。我想知道为什么吗?


代码

这里有许多未使用的函数,这是因为我正在从项目中隔离bug(如果是bug!)。

main.cpp

txBufferLen

IncFile.h

#include "IncFile1.h"

SimpleClass sc;

int main(void)
{
    
    usart_init();
    timer0_init();
    
    sc.transmitter = &usart_send;
    sc.foo();
    
    
    while (1) 
    {
    }
}

SimpleClass.h

#pragma once

#define rxBufferLen 50
#define txBufferLen 50

#include <avr/io.h>
#include "simpleClass.h"

#define TIMER0_CLOCK_PRESCALAR  (3)
#define TIMER0_CLOCK_COUNT      (0xff - 50)

void usart_init();
void timer0_init();
void serial_send_ln(const char *);
void usart_send(uint8_t *,uint8_t);
void usart_send_ln(uint32_t num);

SimpleClass.cpp

#pragma once

typedef unsigned char uint8_t;

#ifndef rxBufferLen
#define rxBufferLen 30
#endif
#ifndef txBufferLen
#define txBufferLen 30
#endif

class SimpleClass{
    uint8_t rxbuffer[rxBufferLen]; ///< receiver buffer
    uint8_t txBuffer[txBufferLen]; ///< transmitter buffer
    uint8_t rxbuff_index,uint8_t len);
    void pushtx(uint8_t byte);
    void pushrx(uint8_t byte);
    void flush();
    void foo();
};

#include "simpleClass.h" void SimpleClass::flush(){ transmitter(txBuffer,txbuff_index); } void SimpleClass::pushtx(uint8_t byte){ txBuffer[txbuff_index++] = byte; } void SimpleClass::pushrx(uint8_t byte){ rxbuffer[rxbuff_index++] = byte; } void SimpleClass::foo(){ uint8_t dv = 0; dv ++ ; pushtx(0x01); pushtx(0x02); pushtx(0x03); pushtx(0x04); pushtx(0x05); flush(); }

CPPFile1.cpp

编辑

解决方法

您违反了“一个定义规则”-链接两次定义相同类的C ++程序这些定义不相同是未定义的行为。不需要编译器/链接器检查或报告这些错误。

您正在这样做:

  • CPPFile1.cpp包括IncFile1.h,该SimpleClassbuffers[50]创建SimpleClass.cpp定义,
  • SimpleClass.h包括buffers[30] cell.addSubview(contentScollView)