Returning a struct from function..error

I am trying to create a function in a custom class that returns a struct. I am getting a prototype mismatch but not sure what I am doing wrong.

Struct in question declared as private.

  typedef struct pumpState_t{
    uint8_t progNum;
    uint16_t Watts;
    uint16_t RPM;
    uint8_t Error;
pumpState_t mainPumpState;

Function to get struct values.

struct pumpState_t myClass::getPumpState(uint8_t xPump)
  return pumpState_t mainPumpState;

Prototype in header file.

struct pumpState_t getPumpState(uint8_t xPump);

@LukeUSMC, would it not be easier (and proper) to toss around pointers instead? :wink:

I imagine so but still haven’t quite wrapped my head around pointers. If I wanted to use that struct in a different class…how would I go about that?

@LukeUSMC, passing structures and objects on the stack is often problematic. With a pointer, you simply define WHAT the pointer is pointing to which in your case is a structure. When you construct that structure (versus just defining it), the pointer allows any object to read/modify its data without knowing where it resides (globally or in an object). You can point to entire objects in the same way!

[quote=“LukeUSMC, post:3, topic:19196”]
If I wanted to use that struct in a different class
[/quote] If you mean “use” in the sense of calling another class object’s function with that structure then using a pointer is the best approach.

Really want I want to do is retrieve member values from the struct for logic within an FSM. Like so?
In myClass…public or private?

pumpState_t * statePointer;
statePointer = &mainPumpState;

In myOtherClass?

currentRPM = statePointer->RPM;

@LukeUSMC, if statePointer is global then yes. If not, you will need to obtain a pointer from the object, using a public pointer var set in the class constructor (or begin function for example) or public class function that returns the pointer.

1 Like

Geez do I have a long way to go! Any pitfalls with using pointers like this? If I understand correctly I can make the statePointer global so any class can see it but this would need to happen AFTER myClass is constructed. Or I could build the pointer in myClass constructor if mainPumpState is public in myClass? Or modify getPumpState to return a pointer to the requesting class?

@LukeUSMC, if you are concerned, build your global pointer (table?) in setup() which runs AFTER all the constructors are built. For complete isolation, call a class function which returns the pointer instead of referring to a specific public variable. You can do this on-the-fly or to build the global pointer(s).

I don’t necessarily have any concerns…not well versed enough to be. I think using a global pointer is best for now, I can move things around later if that proves to be incorrect. I only say that I need to call it after the constructor because I think (this could be extreme lack of compiler knowledge) that the objects for a class are instantiated when the class gets instantiated. So if I tried to create a pointer to something in that class I need to be sure that class objects being pointed to are already instantiated. Could be entirely wrong, the depth of my development experience is entirely in shell scripting and Particle. Objects, Pointers and References are things I am vaguely familiar with but still in my infancy when it comes to their proper use. Thanks for help!

@LukeUSMC, your doing fine! Play around and learn is the best way. I know pointers because of my previous C life. Add objects and it just gets more fun!

A class is actually a struct with a function vector table. You may not need to pass structs to and from your class depending on how you code it. Remember, all the code in the class only uses space once even if instantiated multiple times, so don’t worry about creating lots of the same object with all that code behind it. That’s the beauty of class objects. It’s like a struct that manages and accesses all of it’s variables with isolated code.


See this example I tossed together:

It’ll hopefully give you a more concrete idea of what @peekay123 is talking about. Both methods of “sharing” pump state are covered - opaque pointers as well as getter functions. All the “const” declarations are there to ensure that as long as you don’t jump through hoops to do so, the shared pump state isn’t changed by clients who only wish to read it.


Thank you all so much. That’s awesome @indraastra it all makes a lot more sense now!

1 Like

Ok big help but apparently I am a little show and stuck now. Here is what I am trying to do, could be craziness and absolutely the wrong the way to go but my app looks like the following.

                                              LogicClass<-- -->FSMClass
                                |                 |             |           |
                             Sensors          Weather           Motors       Etc

Weather, Motors, Etc have the same “children” (not derived) in that there is the Class object and struct that stores current state data. I could keep the struct stored away and use getter functions to lock all North-South API calls to pure return function but this doesn’t seem to be common and is a lot of work to avoid pointers. The Logic and FSM are where it all happens and I was trying to keep all of the subclasses (not true children/derived) under LogicClass then pass logic/state info into FSM as needed. Ultimately Logic and FSM need to be able to retrieve/view data from the state structs that are managed entirely in “their” class. So only SensorClass functions should modify sensDataStruct and so. There are some instances where Sensors may need Weather data or something like that so not sure how to handle that. My thinking is that I should create pointers to each Class Object and Subsequent DataStruct from main and make sure I don’t cast and break my rule of no modification outside a class but have read global pointers are poor form. Any help on where the pointers should be defined/declared would be much appreciated.

EDIT: To be clear if I am just way off from something that makes sense/is sustainable I am open to any approach that is effective.

Is it a single instance or multiple? An easy way is to just instantiate and initialize a struct, then pass it to each class object where it copies the pointer in its constructor. Kinda C-like. Of course the pointer is private, but the data is shared, so it’s not really private.

struct pumpState_t{
    uint8_t progNum;
    uint16_t Watts;
    uint16_t RPM;
    uint8_t Error;

class MyClass{
    MyClass(pumpState_t *pState) : m_pState(pState)
    uint16_t getRPM(void)
        return m_pState->RPM;
    pumpState_t *m_pState;

pumpState_t mainPumpState = {0, 10, 10000, 0};
MyClass thing( &mainPumpState );