0

I have a problem when I encode my int array into a message and then decode it in my C# application. When I decode my int array, I get send the encoded bytes to C# by MQTT. I decode it there and all my values are doubled there. I then send the same bytes immidiately back to the NanoPB application where it gets decoded as well, all the values are normal here. What is going on?

My protofile:

syntax = "proto2";

message stringCallback{
    required string name = 1;
    required string surname = 2;
    required int32 age = 3;
    repeated int32 values = 4;
}

My NanoPB encode function:

bool IntArray_encode(pb_ostream_t *ostream, const pb_field_t *field, void* const* arg){
  IntArray* arr = (IntArray*)*arg;
  
  for(int i = 0; i < arr->count; i++){
    if(!pb_encode_tag_for_field(ostream, field)){
      Serial.println("Encoding failed!");
      return false;
    }

    if(!pb_encode_svarint(ostream, arr->values[i])){
      Serial.println("Encoding failed!");
      return false;
    }
  }

  return true;
}

My NanoPB decode function:

bool IntArray_decode(pb_istream_t *stream, const pb_field_t *field, void** arg){
  IntArray* arr = (IntArray*)*arg;
  int64_t number;

  if(!pb_decode_svarint(stream, &number)){
    Serial.println("Decoding failed!");
    return false;
  }

  Serial.println(number);
  IntArray_add(arr, (int32_t)number);

  return true;
}

Output NanoPB:

Name = Testing
Surname = Purpose
Age = 23
[14 11 10 5 109 32321 23 19 15]

Output C#:

Name = Testing
Surname = Purpose
Age = 23
[28 22 20 10 218 64642 46 38 30 ]
J.Meulenbeld
  • 185
  • 1
  • 17

1 Answers1

1

if(!pb_encode_svarint(ostream, arr->values[i])){

The pb_encode_svarint() function is for sint32 and sint64 types.

Your .proto file specifies int32 so you should use pb_encode_varint().

jpa
  • 10,351
  • 1
  • 28
  • 45
  • Then I am not understanding something. When I encode it with pb_encode_varint(), I get the right values on my C#, but then when I use the `pb_decode_varint()` it expects an `unsigned int` as an argument. I do receive the correct value, but if I'm not mistaken, unsigned ints can no go into the negative. But this is what I also want to have. Does this mean that int32_t = uint32_t in the proto file? Because then I will change the proto to use sint32 – J.Meulenbeld Aug 24 '22 at 10:00
  • 1
    @J.Meulenbeld It's just the way the `int32` type in protobuf works, it is basically unsigned integer cast into a signed integer. Use of `sint32` is usually better for negative values: https://stackoverflow.com/questions/48821216/reasons-to-use-int32-in-a-protobuf – jpa Aug 24 '22 at 10:55