Skip to main content
Post Reopened by Avamander
Post Closed as "Not suitable for this site" by CommunityBot, dda, Majenko, per1234, SDsolar
added 2038 characters in body
Source Link
DarioP
  • 142
  • 7

Some samples of the code follows.

Sender:

RS485_Serial bus;
void loop ()
{
  Random r(1); //targeting device 1 in the bus
  if (r.request(bus)) { blink(r.val); } //make a request for a random number
                                        //blink the led the given number of times

  delay(1000);
}

Receiver:

RS485_Serial bus;
bus.set_address(1);
void loop ()
{
  listen(bus);
} 

Selected common parts:

struct Action {
  byte target_address;

  Action(byte addr): target_address(addr) {}
  virtual ~Action() {}

  virtual size_t size() const { return sizeof(*this); }
  virtual int  vrequest(RS485_Serial &) = 0;
  virtual void vrespond(RS485_Serial &) = 0;

  int request(RS485_Serial & bus) {
    bus.write(reinterpret_cast<byte*>(this), size());
    return vrequest(bus);
  }
  void respond(RS485_Serial & bus) {
    vrespond(bus); // <--- This virtual call makes the sender reset
  }
};

struct Random: Action {
  size_t size() const override { return sizeof(*this); }
  int val;
  Random(byte address): Action(address) {}

  int vrequest(RS485_Serial & bus) override {
    return bus.read(val);
  }
  void vrespond(RS485_Serial & bus) override {
    bus.write(static_cast<decltype(val)>(random(2,5)));
  }
};

void listen(RS485_Serial & bus) {
  byte * data = nullptr;
  byte length = 0;
  if ( bus.read(data, length) ){
    Action & a = *(reinterpret_cast<Action*>(data));
    if (a.size() == length) blink(3);
    if (a.target_address == bus.address) {
      a.respond(bus);
      //static_cast<Random*>(&a)->vrespond(); works but it has no point
    }
  }
}

My doubt is that if the vtable is stored in different positions, than the vtable pointer in the object obtained by the receiver will be off, causing the crash.

Some samples of the code follows.

Sender:

RS485_Serial bus;
void loop ()
{
  Random r(1); //targeting device 1 in the bus
  if (r.request(bus)) { blink(r.val); } //make a request for a random number
                                        //blink the led the given number of times

  delay(1000);
}

Receiver:

RS485_Serial bus;
bus.set_address(1);
void loop ()
{
  listen(bus);
} 

Selected common parts:

struct Action {
  byte target_address;

  Action(byte addr): target_address(addr) {}
  virtual ~Action() {}

  virtual size_t size() const { return sizeof(*this); }
  virtual int  vrequest(RS485_Serial &) = 0;
  virtual void vrespond(RS485_Serial &) = 0;

  int request(RS485_Serial & bus) {
    bus.write(reinterpret_cast<byte*>(this), size());
    return vrequest(bus);
  }
  void respond(RS485_Serial & bus) {
    vrespond(bus); // <--- This virtual call makes the sender reset
  }
};

struct Random: Action {
  size_t size() const override { return sizeof(*this); }
  int val;
  Random(byte address): Action(address) {}

  int vrequest(RS485_Serial & bus) override {
    return bus.read(val);
  }
  void vrespond(RS485_Serial & bus) override {
    bus.write(static_cast<decltype(val)>(random(2,5)));
  }
};

void listen(RS485_Serial & bus) {
  byte * data = nullptr;
  byte length = 0;
  if ( bus.read(data, length) ){
    Action & a = *(reinterpret_cast<Action*>(data));
    if (a.size() == length) blink(3);
    if (a.target_address == bus.address) {
      a.respond(bus);
      //static_cast<Random*>(&a)->vrespond(); works but it has no point
    }
  }
}

My doubt is that if the vtable is stored in different positions, than the vtable pointer in the object obtained by the receiver will be off, causing the crash.

Source Link
DarioP
  • 142
  • 7

Send a polymorphic object over serial

I am sending a polymorphic object over serial between two Arduinos. The transmission should be fine, indeed if on the receiver side I static_cast the pointer to the Derived class it works properly. On the other hand if I try to call virtual functions on the Base pointer, Arduino resets. What is causing this behaviour?