Re: Dynamic Message and google::protobuf::Message incompatibility

1,117 views
Skip to first unread message

Feng Xiao

unread,
Jan 17, 2013, 1:10:49 AM1/17/13
to prot...@googlegroups.com


On Thursday, January 17, 2013 8:15:53 AM UTC+8, m wrote:
Hi All,

I'm seeing an incompatibility between a dynamically generated google::protobuf::Message (DynamicMessage?) created with a google::protobuf::DynamicMessageFactory and a normal google::protobuf::Message.

What I'm running up against ultimately comes down to this: I can't dynamic_cast a DynamicMessage to a known derived type of google::protobuf::Message.  For example, let's say my proto file has the following message:

package my.package;

messsage Foo
{
  string blah = 1;
  uint32 bleh = 2;
}

and I successfully create a my::package::Foo with some code along the lines of:

const google::protobuf::Descriptor* descriptor = myImporter.pool()->FindMessageTypeByName( "my.package.Foo" );

google::protobuf::Message* message = myDynamicMessageFactory.GetPrototype( descriptor )->New();

after populating message successfully with other commands not shown here, I try to do something like:

my::package::Foo foo;
foo.CopyFrom( *message );

and I get a segfault in CopyFrom() because ultimately the following doesn't work (the pointer pFoo ends up being NULL down inside CopyFrom()/MergeFrom()):
CopyFrom() should be able to copy a DynamicMessage to a generated message if they share the same descriptor.
Can you post the whole generated method where the segfault happens?
 

my::package::Foo* pFoo = dynamic_cast< my::package::Foo* >( message );

It appears as though the derived type of message is not actually my::package::Foo, but instead google::protobuf::DynamicMessage (or something like that), so naturally the dynamic_cast fails.  I was sure to observe the output of message->DebugString() and message->GetTypeName() which returned all the appropriate information.

Is there any way to get a real my::package::Foo object from a dynamic one?
 

m

unread,
Jan 17, 2013, 2:31:48 PM1/17/13
to prot...@googlegroups.com
Thanks for your reply.

My application links against all the stub proto sources of the types I will be creating.  What I've found works is if I use the default(?) descriptor pool (google::protobuf::DescriptorPool::generated_pool()) and the default message factory (google::protobuf::MessageFactory::generated_factory()).  Given the type name and the content, I have a simple function that more or less does this:

const gpb::Descriptor* descriptor = gpb::DescriptorPool::generated_pool()->FindMessageTypeByName( "my.package.Foo" );
 
gpb::MessageFactory* factory = gpb::MessageFactory::generated_factory();
 

const gpb::Message* prototype = factory->GetPrototype( descriptor );
 

gpb::Message* message = prototype->New();
 
gpb::Message* m = gpb::TextFormat::ParseFromString( "blah: \"some string\" bleh: 3", message );




On Wednesday, January 16, 2013 4:15:53 PM UTC-8, m wrote:
Hi All,

I'm seeing an incompatibility between a dynamically generated google::protobuf::Message (DynamicMessage?) created with a google::protobuf::DynamicMessageFactory and a normal google::protobuf::Message.

What I'm running up against ultimately comes down to this: I can't dynamic_cast a DynamicMessage to a known derived type of google::protobuf::Message.  For example, let's say my proto file has the following message:

package my.package;

messsage Foo
{
  string blah = 1;
  uint32 bleh = 2;
}

and I successfully create a my::package::Foo with some code along the lines of:

const google::protobuf::Descriptor* descriptor = myImporter.pool()->FindMessageTypeByName( "my.package.Foo" );

google::protobuf::Message* message = myDynamicMessageFactory.GetPrototype( descriptor )->New();

after populating message successfully with other commands not shown here, I try to do something like:

my::package::Foo foo;
foo.CopyFrom( *message );

and I get a segfault in CopyFrom() because ultimately the following doesn't work (the pointer pFoo ends up being NULL down inside CopyFrom()/MergeFrom()):

m

unread,
Jan 17, 2013, 2:37:04 PM1/17/13
to prot...@googlegroups.com
Sorry, there's a typo on that last line.  It should be:

gpb::TextFormat::ParseFromString( "blah: \"some string\" bleh: 3", message );

Feng Xiao

unread,
Jan 18, 2013, 1:20:13 AM1/18/13
to prot...@googlegroups.com
Glad that you found what works for you. What baffles me is why CopyFrom() segfaults when given a DynamicMessage.  DynamicMessage can't be cast to Foo, but foo.CopyFrom() gets to be working with it. Did you find why it segfaults?

m

unread,
Jan 18, 2013, 1:13:30 PM1/18/13
to prot...@googlegroups.com
The furthest I followed it was looking down into the implementation of CopyFrom() which calls MergeFrom().  Inside of MergeFrom() there's a spot where it calls something like "dynamic_cast_if_available" which returns NULL (failing to dynamic_cast).

Feng Xiao

unread,
Jan 21, 2013, 1:50:34 AM1/21/13
to m, prot...@googlegroups.com
On Sat, Jan 19, 2013 at 2:13 AM, m <mike...@gmail.com> wrote:
The furthest I followed it was looking down into the implementation of CopyFrom() which calls MergeFrom().  Inside of MergeFrom() there's a spot where it calls something like "dynamic_cast_if_available" which returns NULL (failing to dynamic_cast).
Returning NULL shouldn't cause a segment fault. The generated code should be able to handle this NULL case properly.
 
--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To view this discussion on the web visit https://groups.google.com/d/msg/protobuf/-/iGRNOvXkgtEJ.

To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.

Reply all
Reply to author
Forward
0 new messages