How do I get access to a response object of type pb_callback_t ?

56 views
Skip to first unread message

Renegade

unread,
Feb 10, 2025, 1:16:23 AMFeb 10
to nanopb
Hi,

I have made a request, and get a response as follows:

 rustplus_AppTeamInfo team = response.response.teamInfo;
 pb_callback_t member = team.members; // how do i parse this?
The challenge I have is this team.members.

This should be an array of member objects, which are defined as:

message AppTeamInfo {
required uint64 leaderSteamId = 1;
repeated AppTeamInfo.Member members = 2;
repeated AppTeamInfo.Note mapNotes = 3;
repeated AppTeamInfo.Note leaderMapNotes = 4;

message Member {
required uint64 steamId = 1;
required string name = 2;
required float x = 3;
required float y = 4;
required bool isOnline = 5;
required uint32 spawnTime = 6;
required bool isAlive = 7;
required uint32 deathTime = 8;
}

message Note {
required int32 type = 2;
required float x = 3;
required float y = 4;
optional int32 icon = 5;
optional int32 colourIndex = 6;
optional string label = 7;
}
}

How do I use this callback type to get access to each of the members in this structure!

Thank you very much in advance!

Petteri Aimonen

unread,
Feb 10, 2025, 1:20:59 AMFeb 10
to nanopb
Hi,

The reason why repeated items are more complicated is that the amount of memory they will take is not known.
There are a few ways to deal with this:

1. Specify max_count
If you know in ahead a maximum number of items in the repeated arrays, you can specify it as max_count:

import 'nanopb.proto';
...
repeated AppTeamInfo.Member members = 2 [(nanopb).max_count = 10];

Then you get a regular C array which you can access.

2. Use dynamic allocation (PB_ENABLE_MALLOC)
Then malloc() is used to allocate the memory.

3. Use callback functions
With callback functions, you register a function that will be called for every item in the array.
Then you need to store it somewhere yourself.

--
Petteri

Renegade

unread,
Feb 10, 2025, 6:17:55 AMFeb 10
to nanopb
Hi Petteri,

Thank you for your response.

I won't know the max_count as it is not known and could adjust. Therefore I like the look of option 2.

I have added 

#define PB_ENABLE_MALLOC 1 to the top of pb.h.

What will I do now within my code to get access to the members array? Do I need to change something in the proto file?

Petteri Aimonen

unread,
Feb 10, 2025, 6:22:12 AMFeb 10
to nanopb
Hi,

Yes, you need to set the field as `FT_POINTER`. For example:

repeated AppTeamInfo.Member members = 2 [(nanopb).type = FT_POINTER];

And remember to call pb_release() after you are done with the message.

--
Petteri

Renegade

unread,
Feb 10, 2025, 9:22:30 AMFeb 10
to nanopb
Okay - and do I then need to regenerate the header and c files?

Renegade

unread,
Feb 10, 2025, 9:22:36 AMFeb 10
to nanopb
Hi,

Okay I used that line and now I ge an array of member structs -- nice.

Next issue is that the 'name' field of member as per the first posts proto is declared as a String. For some reason in my code it is showing as:

 pb_callback_t name;
How do I turn *this* callback into a char *?


On Monday, 10 February 2025 at 11:22:12 UTC petteri...@gmail.com wrote:

Petteri Aimonen

unread,
Feb 10, 2025, 9:23:23 AMFeb 10
to nanopb
Hi,

It is exactly the same, either specify maximum length for the string or use dynamic allocation.

--
Petteri

Renegade

unread,
Feb 10, 2025, 9:53:05 AMFeb 10
to nanopb
Hi Petteri,

Thanks for your consistent support.

I changed the proto to have:

required string name =  2 [(nanopb).type = FT_POINTER];

and regenerated. I then get a char * but when i display that, it just has chunk in it?

Renegade

unread,
Feb 10, 2025, 9:57:58 AMFeb 10
to nanopb
Scratch that - I made a mistake. It's absolutely working - thank you!

On Monday, 10 February 2025 at 14:23:23 UTC petteri...@gmail.com wrote:

Renegade

unread,
Feb 10, 2025, 2:23:51 PMFeb 10
to nanopb
I am looking at using pb_release as you suggested.

I am calling release for each of the member objects I receive. This works well as per:

  pb_release(rustplus_AppTeamInfo_Member_fields,&member);
After that, I then attempt to release the teaminfo object as well, but that causes the esp32 to crash. The line in question is:

     rustplus_AppTeamInfo team = response.response.teamInfo;
   
      int members = team.members_count;
      Serial.printf("Team size is: %i",members);
     for(int i=0;i<members;i++){
       _rustplus_AppTeamInfo_Member member = team.members[i];
       player_online(member.name,member.isOnline);
       pb_release(rustplus_AppTeamInfo_Member_fields,&member);
      }
      pb_release(rustplus_AppTeamInfo_fields,&team);  ------- THIS LINE

Any ideas why this is crashing the application? Is it because this gets tidied automatically? I suppose I just used malloc for the members array, and the name variables, both of which are tidied by pb_release of &member?

Maybe thats enough?

Petteri Aimonen

unread,
Feb 11, 2025, 1:24:48 AMFeb 11
to nan...@googlegroups.com
Hi,

You only need to call pb_release() on the main message, the same
as you passed to pb_decode(). It releases everything contained there.

If you need to release (or keep) the submessages individually,
you should then remove them from the main message array (set its count to 0).

--
Petteri
> >>>>>> *1. Specify max_count*
> >>>>>> If you know in ahead a maximum number of items in the repeated
> >>>>>> arrays, you can specify it as max_count:
> >>>>>>
> >>>>>> import 'nanopb.proto';
> >>>>>> ...
> >>>>>> repeated AppTeamInfo.Member members = 2 [(nanopb).max_count = 10];
> >>>>>>
> >>>>>> Then you get a regular C array which you can access.
> >>>>>>
> >>>>>> *2. Use dynamic allocation (PB_ENABLE_MALLOC)*
> >>>>>> Then malloc() is used to allocate the memory.
> >>>>>>
> >>>>>> *3. Use callback functions*
> --
> You received this message because you are subscribed to the Google Groups "nanopb" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to nanopb+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/nanopb/349d2419-02e8-4821-a5bf-9b4043c6cae4n%40googlegroups.com.

> I am looking at using pb_release as you suggested.
> I am calling release for each of the member objects I receive. This
> works well as per:
>
> pb_release(rustplus_AppTeamInfo_Member_fields,&member);
>
> After that, I then attempt to release the teaminfo object as well, but
> that causes the esp32 to crash. The line in question is:
>
> rustplus_AppTeamInfo team = response.response.teamInfo;
>
> int members = team.members_count;
> Serial.printf("Team size is: %i",members);
> for(int i=0;i<members;i++){
> _rustplus_AppTeamInfo_Member member = team.members[i];
> player_online(member.name,member.isOnline);
> pb_release(rustplus_AppTeamInfo_Member_fields,&member);
> }
> pb_release(rustplus_AppTeamInfo_fields,&team); ------- THIS LINE
>
> Any ideas why this is crashing the application? Is it because this gets
> tidied automatically? I suppose I just used malloc for the members
> array, and the name variables, both of which are tidied by pb_release
> of &member?
>
> Maybe thats enough?
>
> On Monday, 10 February 2025 at 14:57:58 UTC Renegade wrote:
>
> Scratch that - I made a mistake. It's absolutely working - thank
> you!
>
> On Monday, 10 February 2025 at 14:23:23 UTC [1]petteri...@gmail.com
> See [2]https://jpa.kapsi.fi/nanopb/docs/concepts.html#field-callbacks
> --
> You received this message because you are subscribed to the Google
> Groups "nanopb" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [3]nanopb+un...@googlegroups.com.
> To view this discussion visit
> [4]https://groups.google.com/d/msgid/nanopb/349d2419-02e8-4821-a5bf-9b4
> 043c6cae4n%40googlegroups.com.
>
> References
>
> 1. file:///tmp/neomutt.html
> 2. https://jpa.kapsi.fi/nanopb/docs/concepts.html#field-callbacks
> 3. mailto:nanopb+un...@googlegroups.com
> 4. https://groups.google.com/d/msgid/nanopb/349d2419-02e8-4821...@googlegroups.com?utm_medium=email&utm_source=footer


Reply all
Reply to author
Forward
0 new messages