Error when using strings

354 views
Skip to first unread message

to...@grexor.com

unread,
Sep 27, 2018, 11:48:14 AM9/27/18
to nanopb
Ok so I modified the simple example to add a string data = 2; to de .proto.
So my simple.proto is the following:

syntax = "proto2";

message SimpleMessage {
required int32 lucky_number = 1;
optional string data = 2;
}

But after I decode it, when I try to print, or manipulate the data with any str function, the compiler yells at me with this:

tutorial.c:73:19: error: incompatible type for argument 1 of ‘strcmp’
if(strcmp(message.data, "AyL")) {
^
In file included from /home/tomas/Documents/libraries/nanopb/pb.h:68:0,
from /home/tomas/Documents/libraries/nanopb/pb_encode.h:9,
from tutorial.c:2:
/usr/include/string.h:140:12: note: expected ‘const char *’ but argument is of type ‘pb_callback_t {aka struct pb_callback_s}’
extern int strcmp (const char *__s1, const char *__s2)


When I run the simple example there's no problem and works like a charm.

$ protoc --version
libprotoc 3.1.0

What am I doing wrong?
Thanks!
Tomas
tutorial.c
tutorial.proto

Petteri Aimonen

unread,
Sep 27, 2018, 12:01:54 PM9/27/18
to nan...@googlegroups.com
Hi,

> But after I decode it, when I try to print, or manipulate the data
> with any str function, the compiler yells at me with this:
> /usr/include/string.h:140:12: note: expected ‘const char *’ but
> argument is of type ‘pb_callback_t {aka struct pb_callback_s}’
> extern int strcmp (const char *__s1, const char *__s2)

The complication with strings is that their length may vary, but in
embedded systems you usually don't have large amounts of memory
available.

Nanopb offers several ways to deal with this:
https://jpa.kapsi.fi/nanopb/docs/concepts.html#data-types

1) Specifying a maximum size, in either the .proto file or in a separate
.options file. This gives a char array you can use directly with
strcmp().

2) Using callback functions. Instead of decoding the string in one go,
the callback function can decide what to do with it. This is the default
if maximum size is not specified.

3) Using malloc() to allocate memory in runtime.

Of these, 1) is usually what you want, but nanopb cannot guess the
maximum size for the string and you have to specify it.

This example may also be helpful, because it uses strings and arrays:
https://github.com/nanopb/nanopb/tree/master/examples/network_server

--
Petteri

to...@grexor.com

unread,
Sep 27, 2018, 12:20:49 PM9/27/18
to nanopb
Oh thanks Petteri, I knew it had something to do with memory but just couldn't find a solution.
Maybe a hint could be added to the Readme file at the repo haha, I searched the web for my particular error but didn't find anything linking to the official docs!

Thank you very much for the fast and complete response!
Excelent work.

Tomas

Petteri Aimonen

unread,
Sep 27, 2018, 12:23:33 PM9/27/18
to nan...@googlegroups.com
Hi,

> Maybe a hint could be added to the Readme file at the repo haha, I
> searched the web for my particular error but didn't find anything
> linking to the official docs!

Yeah, it's not that clear. I guess the error message is not that common,
because it varies what functions people might try to use.

I've been meaning to write a tutorial series which would explain these
basics, but it's something I've been meaning to do since 2014.. :)

--
Petteri

to...@grexor.com

unread,
Sep 27, 2018, 12:32:15 PM9/27/18
to nanopb
I know what you mean, It's no easy finding time for side projects.
Great job any way!

to...@grexor.com

unread,
Sep 27, 2018, 1:09:56 PM9/27/18
to nanopb

> 1) Specifying a maximum size, in either the .proto file or in a separate
> .options file. This gives a char array you can use directly with
> strcmp().

> Petteri

I just added the .options but for some reason the compiler keeps crashing with the same error. So this time I went to the docs (http://jpa.kapsi.fi/nanopb/docs/reference.html#defining-the-options-in-a-options-file) and run the debug command:

$ protoc . --nanopb_out=-v:. message.proto

[libprotobuf WARNING google/protobuf/compiler/parser.cc:546] No syntax specified for the proto file: . Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.)
protoc-gen-nanopb: program not found or is not executable
--nanopb_out: protoc-gen-nanopb: Plugin failed with status code 1.

That command was run at ~/Docs/libraries/nanopb/projects/tutorial is that messing with something?

It's weird because I do have syntax specified (my proto is attached to the original post). This time I attached my .options along with my Makefile.

Am I missing something too obvious?
Sorry for the trouble.

Tomas

tutorial.options
Makefile

Petteri Aimonen

unread,
Sep 27, 2018, 1:45:45 PM9/27/18
to nan...@googlegroups.com
Hi,

> I just added the .options but for some reason the compiler keeps
> crashing with the same error. So this time I went to the docs
> (http://jpa.kapsi.fi/nanopb/docs/reference.html#defining-the-options-in-a-options-file)
> and run the debug command:

It's actually a warning and an error:

> [libprotobuf WARNING google/protobuf/compiler/parser.cc:546] No syntax
> specified for the proto file: . Please use 'syntax = "proto2";' or
> 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2
> syntax.)

This is just a warning. Not sure why you'd get it, if you have syntax
specification in the .proto file. Though your command calls it
message.proto and you attached tutorial.proto.

> protoc-gen-nanopb: program not found or is not executable

This is the error that prevents the compilation.

Problem is when protoc is trying to find the protoc-gen-nanopb
executable. It works automatically when either protoc-gen-nanopb is
installed system-wide and you use system-wide protoc, or if you use the
binary package and you use the protoc included with the binary package.

But otherwise when you use system-wide protoc with a source checkout, it
needs to be given the path to the protoc-gen-nanopb in the generator
folder. The Makefile rules included from nanopb.mk do this
automatically, but they do it by setting the variable PROTOC_OPTS. Your
Makefile happens to override this variable.

I'd suggest you do the following:

1) Change your Makefile to "PROTOC_OPTS += -Isubdir" so that it only
adds options and doesn't remove the existing ones.

2) After that, run "make -B" so that you see the protoc command line. It
probably has something like --plugin=... on it, and you need to include
that in your own commands also.

--
Petteri

to...@grexor.com

unread,
Sep 28, 2018, 9:39:50 AM9/28/18
to nanopb

> I'd suggest you do the following:
>
> 1) Change your Makefile to "PROTOC_OPTS += -Isubdir" so that it only
> adds options and doesn't remove the existing ones.
>
> 2) After that, run "make -B" so that you see the protoc command line. It
> probably has something like --plugin=... on it, and you need to include
> that in your own commands also.
>
> --
> Petteri

Gave it a clean start and created a new project. Don't know exactly what was the problem but it seems to be working fine now (set back the makefile to the original simple example). I've managed to get the string type working. The only curious thing I've found is that can't seem to encode optional data types. Doesn't matter if it's int32 or string, when I try to code it, they both decode to 0 and "" respectively. Couldn't find anything in the docs.

Petteri Aimonen

unread,
Sep 28, 2018, 10:20:44 AM9/28/18
to nan...@googlegroups.com
Hi,

> The only curious thing I've found is that can't seem to encode
> optional data types. Doesn't matter if it's int32 or string, when I
> try to code it, they both decode to 0 and "" respectively. Couldn't
> find anything in the docs.

Look at the generated .pb.h file. You'll find that optional fields have
a separate 'has_field' that you need to set true. Looks like it is not
mentioned in the docs much.

--
Petteri


to...@grexor.com

unread,
Sep 28, 2018, 11:37:28 AM9/28/18
to nanopb

> Look at the generated .pb.h file. You'll find that optional fields have
> a separate 'has_field' that you need to set true. Looks like it is not
> mentioned in the docs much.
>
> --
> Petteri

Oh ok great, I changed the following line:

#define SimpleMessage_init_default {0, true, ""}

That solved the issue.
Thanks!

Reply all
Reply to author
Forward
0 new messages