ExtensionRegistry registry = ...
registry.add(...);
Foo.parseFrom(buf, registry)
but I can't find any reference on how to do this in C++.
--
/Jesper
I wonder why it isn't working for me, then. I'm serializing an object
from Java with an extension set, but when parsing it in C++, the
extension field is unset. I'll have to dig some deeper tomorrow.
(Annoying time-zone lag. You're replying just around my bedtime. :-))
--
/Jesper
---------- Forwarded message ----------
From: Jesper Eskilson <jes...@eskilson.se>
Date: Thu, Aug 27, 2009 at 9:23 AM
Subject: Re: Parsing messages in C++ with extensions
To: Kenton Varda <ken...@google.com>
On Thu, Aug 27, 2009 at 12:18 AM, Kenton Varda<ken...@google.com> wrote:
> Some linkers will drop object files that aren't referenced from anywhere, so
> if your code doesn't actually use anything from the .proto file defining the
> extension, it might not be linked in, and thus won't be in the registry.
> This is one of the common problems that make me wish we had an explicit
> ExtensionRegistry in C++...
> Otherwise, I don't know what your problem might be. If you can narrow it
> down to a small self-contained example I could debug it.
Well, hm. I don't seem to be linking with the defining code. That
would probably explain it.
Would an explicit extension-registry be difficult to implement?
What's the recommended way of solving the problem? Linking in all the
protocol definitions in the same module is something I'd like to
avoid. Is there a way I can extract the "unknown" field and pass it to
the "defining module" for further parsing?
--
/Jesper
--
/Jesper
You're right. I first needed to link all of the *.pb.cc files into
library doing the parsing, but as you said, MSVC drops the code unless
I explicitly refer to some code in it.
This is really annoying.
--
/Jesper
This is really not feasible. There is no such place, unfortunately.
> BTW, if you aren't actually explicitly using the extension anywhere, then
> the only reason to force it to be linked in is if you want it to appear
> correctly when using reflection or TextFormat. Otherwise you should just
> let it go into the UnknownFieldSet.
The situation is this: I have a main program which parses incoming
messages, and some of these messages have extensions set. These
extensions are (sometimes) only known to "plugins" to the main
program. The incoming message has an identifier so that the main
program knows which plugin it should send the message to, but the main
program itself doesn't know anything about the plugin. The problem I
had was that when the message was passed to the plugin, the plugin
fails to get the extension, i.e. the extension field was unset (i.e.
HasExtension(foo::foo_ext) returned false).
Does the UnknownFieldSet allow the plugin to extract the "unknown field"?
The original solution to this I had before I read up on extensions was
to store the messages to/from the plugins as seralized byte-streams in
the top-level package. This actually worked fine, with the exception
of having to encode/copy the message twice at both ends.
--
/Jesper
Ok, thanks for the detailed explanation. I think I have enough info on
this for the time being.
--
/Jesper
> To answer your specific question, BTW, yes, you can inspect the contents of
> UnknownFieldSet. Every message object has methods unknown_fields() and
> mutable_unkown_fields() which return the UnknownFieldSet. The API is
> described here:
> http://code.google.com/apis/protocolbuffers/docs/reference/cpp/google.protobuf.unknown_field_set.html
I'm probably missing something, but I get a complation error when
trying to access the unknown fields of a message:
Error 1 error C2248:
'google::protobuf::UnknownFieldSet::UnknownFieldSet' : cannot access
private member declared in class 'google::protobuf::UnknownFieldSet';
e:\dev\ide-platform\core\ide\protobuf\src\google/protobuf/unknown_field_set.h(124)
: see declaration of
'google::protobuf::UnknownFieldSet::UnknownFieldSet';
e:\dev\ide-platform\core\ide\protobuf\src\google/protobuf/unknown_field_set.h(63)
: see declaration of
'google::protobuf::UnknownFieldSet' e:\dev\ide-platform\core\ide\CSpyServer\src\model\CssListWindowService.cpp 21
The code looks like this:
void
foo(const cdp::DebugCommand &cmd)
{
UnknownFieldSet set = cmd.GetReflection()->GetUnknownFields(cmd);
}
--
/Jesper
Ok, so if I have function which receives a message which as an unknown
field which I need to parse into a "real" message, how should I do?
(The documentation is a little fuzzy on this...)
I tried to call ParseFromString() on the string returned by
length_delimited(), but that just crashed.
const UnknownFieldSet& set = cmd.unknown_fields();
const UnknownField f = set.field(0);
const std::string &buf = f.length_delimited();
listwindow::ListWindowCommand lwc;
lwc.ParseFromString(buf);
--
/Jesper
On Thu, Sep 3, 2009 at 6:56 PM, Kenton Varda<ken...@google.com> wrote:Ok, so if I have function which receives a message which as an unknown
> You want:
> const UnknownFieldSet& set = cmd.GetReflection()->GetUnknownFields(cmd);
field which I need to parse into a "real" message, how should I do?
(The documentation is a little fuzzy on this...)
I tried to call ParseFromString() on the string returned by
length_delimited(), but that just crashed.
const UnknownField f = set.field(0);
const UnknownFieldSet& set = cmd.unknown_fields();