BillP
BillP

Reputation: 3

Global protobuf message

I am experiencing problems with a protobuf message that is instantiated during static initialization. Some functions like DebugPrint() causes crashes, and serialization fails with the error that there is a mismatch in the size.

Considering https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.common#ShutdownProtobufLibrary.details and looking at the generated mymessage.pb.cc file, I believe the issue is that the message's static initializers have not been called yet.

Does anybody know whether I can enforce, in a somewhat "legal" way, that the message's static initializers are called beforehand (or that I call them)? From looking at the generated code I could just call some magically appearing function, but this seems likely to break. Or is this just something I've got to live with and initialize the message lazy?

Upvotes: 0

Views: 1621

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45151

Try calling MyType::default_instance() at least once before you try to use MyType. This triggers a bunch of initialization that may cover your needs.

If that doesn't work, then you're going to need to find some way to cause the .pb.o's dynamic initializers to run before your own code's. It may be that this is dependent on the order in which the objects are listed on the linker command line, and you can "fix" the problem by changing that order, although this is obviously a terrible hack.

If that also doesn't work, then you're out of luck. Instead of relying on dynamic initialization, consider using pthread_once or Win32's InitOnce to initialize your data on first use.

FWIW, Cap'n Proto, a newer alternative to Protobufs from the same author (me), has a strict no-dynamic-initializers policy, so does not have this kind of problem.

(Terminology nitpick: "Static initialization" refers to initializers where the resulting memory content is known at compile time, therefore require no code to be executed at startup. This includes e.g. globals of primitive types or constexprs. "Dynamic initialization" refers to constructors that run at startup, which is what you're talking about here. Admittedly, almost everyone gets this wrong, including myself historically.)

Upvotes: 2

Related Questions