complex problem - XBee, external libraries and passing structures as arguments

I have very weird problem with a library I am creating. The library will be used to communicate between Arduino modules using XBee Series 1 modules. Library is very simple wrapper library around Arduino XBee library.

At one point I need to pass a structure as an argument to one of the functions in the library. This is the function that is responsible for creating a response packet and sending it. I will illustrate the problem using simple example of an "echo service" library - Arduino sends back to a given address the content of the packet that was received.

I want to pass to the function that processes the packet a structure with some data. However, I noticed when I pass the structure, the behavior of other (seemingly non related) parts of code is different. Namely, if I pass as structure to the function as a value, received packet will be read by XBee not correctly. If I pass a structure by a pointer, the behavior is correct. Below there is a simple example that illustrates my problem.

Library:

ExampleLib.h

#ifndef ExampleLib_h
#define ExampleLib_h

#include "Arduino.h"
#include <XBee.h>

#define ADDRESS_BROADCAST 0xffff
#define ADDRESS_PC 0x3333

typedef struct
  {
    int valA;
    int valB;
    int valC;
  } valuesStruct;

class ExampleLib
{
public:
    ExampleLib();
    void setSerial(Stream &serial);
    boolean tryReceivePacket();
    void processPacket();
    // THIS FUNCTION IS NOT WORKING!
    void processPacket(valuesStruct valuesStructData);
    void processPacket(valuesStruct* valuesStructData);
private:
    XBee xbee;
    Rx16Response rx16;
};

#endif

ExampleLib.cpp
As you cna see here, I have three 'processPacket' functions that differ only by an argument passed - no argument, structure or structure pointer. In case of no argument and structure pointer the behavior of the function is correct, in case of a structure behavior is not correct and I cannot explain it - data read by " rx16.getData()" is not correct.

#include "Arduino.h"
#include <XBee.h>
#include "ExampleLib.h"

ExampleLib::ExampleLib()
{
	xbee = XBee();
	rx16 = Rx16Response();
}

void ExampleLib::setSerial(Stream &serial)
{
	xbee.setSerial(serial);
}

boolean ExampleLib::tryReceivePacket()
{
	xbee.readPacket();

  if (xbee.getResponse().isAvailable()) {
    // got something

    if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
      // got a rx packet

      xbee.getResponse().getRx16Response(rx16);
      return true;
    } 
    else {
      return false;
    }
  } 
  else if (xbee.getResponse().isError()) {
    //nss.print("Error reading packet.  Error code: ");  
    //nss.println(xbee.getResponse().getErrorCode());
    // or flash error led
    return false;
  } 
  
  return false;
}
void ExampleLib::processPacket()
{
  byte* packetData = rx16.getData();
  byte dataLength = rx16.getDataLength();
  Serial.print("START L:");
  Serial.println(dataLength);
  for (int i = 0; i < dataLength; i++) { 
    Serial.print(packetData[i]);
	Serial.print(" - "); 
  }
  Serial.println("END");
  
  //16-bit addressing: Enter address of remote XBee, typically the coordinator
  Tx16Request tx = Tx16Request(ADDRESS_PC, packetData, sizeof(packetData));
  xbee.send(tx);
}

void ExampleLib::processPacket(valuesStruct valuesStructData)
{
  processPacket();
}

void ExampleLib::processPacket(valuesStruct* valuesStructData)
{
  processPacket();
}

sketch

#include <XBee.h>
#include <ExampleLib.h>

ExampleLib exampleLibObj = ExampleLib();

void setup()
{
  Serial.begin(9600);
  exampleLibObj.setSerial(Serial);
}

void loop()
{

  boolean isPacketReceived = exampleLibObj.tryReceivePacket();

  if (isPacketReceived) {
    // leave only one section, the rest should be commented
    
    //Section 1: working
    exampleLibObj.processPacket();
    
    //Section 2: not working
//    valuesStruct test;
//    test.valA = 0;
//    test.valB = 0;
//    test.valC = 0;
//    exampleLibObj.processPacket(test);

    //Section 3: working
//  valuesStruct* test;
//  test->valA = 0;
//  test->valB = 0;
//  test->valC = 0;
//  exampleLibObj.processPacket(test);
  }
}

Basically, we trigger the same function, and a behavior differs if we use a structure as an argument (although we never use or call this structure). This is a very mysterious behavior to me. Do you have any idea what can be the problem?

Thanks in advance for any help.
Michal

C (and C++) are pass by value languages. Passing a struct (a complex data type) is not a good idea. Use global instances, pass by reference, or pass a pointer. Do not try to pass a struct instance directly.