2014-11-23 2 views
0

정적 초기화 중에 인스턴스화되는 protobuf 메시지에 문제가 있습니다. DebugPrint()와 같은 일부 함수는 충돌을 일으키고 크기가 일치하지 않는다는 오류와 함께 직렬화가 실패합니다.전체 프로토 타입 메시지

https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.common#ShutdownProtobufLibrary.details을 고려하고 생성 된 mymessage.pb.cc 파일을 보면 메시지의 정적 초기화 프로그램이 아직 호출되지 않았다는 것이 문제라고 생각합니다.

메시지의 정적 이니셜 라이저가 미리 호출되는지 (또는 내가 호출 한 것인지) 어느 정도 "합법적 인"방법으로 적용 할 수 있는지 여부를 아는 사람이 있습니까? 생성 된 코드를 살펴보면 마술처럼 보이는 기능을 호출 할 수 있지만이 기능은 중단 될 수 있습니다. 아니면이 게 내가 살고 게으른 메시지를 초기화해야만하는 것입니까?

답변

1

MyType을 사용하기 전에 적어도 한 번 이상 MyType::default_instance()을 호출 해보십시오. 이것은 사용자의 필요를 충족시킬 수있는 일련의 초기화를 트리거합니다.

그래도 작동하지 않는다면 .pb.o의 동적 이니셜 라이저가 자신의 코드보다 먼저 실행되도록하는 방법을 찾아야 할 것입니다. 이것은 링커 명령 행에 객체가 나열된 순서에 따라 달라질 수 있으며이 순서를 변경하여 문제를 "고칠 수"있습니다. 물론 이것은 끔찍한 해킹입니다.

그래도 작동하지 않으면 운이 없어집니다. 동적 초기화에 의존하는 대신 pthread_once 또는 Win32 's InitOnce을 사용하여 처음 사용할 때 데이터를 초기화하는 것이 좋습니다.

동일한 저자 (me)의 Protobufs보다 새로운 대안 인 FWIW, Cap'n Proto에는 엄격한 no-dynamic-initializers 정책이 있으므로 이러한 종류의 문제는 없습니다.

(용어 설명 : "정적 초기화"는 결과 메모리 내용을 컴파일 할 때 알 수있는 초기화 프로그램을 말합니다. 따라서 시작시 코드를 실행하지 않아도됩니다. 예 : 전역 유형이 기본 유형이거나 constexpr입니다. "동적 초기화 거의 모든 사람들이 역사적으로 나 자신을 포함하여이 오류를 가져옵니다.)

+0

실제로 default :: instance() 호출을 stumpled하고 보았습니다. 정말로 유망한. 그러나 그것은 아무런 차이가없는 것처럼 보입니다 .-- 그리고 연결 순서는 실제로 피하고 싶습니다. – BillP

+0

글쎄, 게으른 초기화를 사용해야 할 것입니다. 어쨌든 좋은 생각입니다. 예를 들어, protobufs를 사용할 때 Chrome에 많은 문제가 발생했기 때문에 Cap'n Proto의 동적 초기화 프로그램을 피할 수 있습니다. 싱글 톤] (http://www.object-oriented-security.org/lets-argue/singletons)을 참조하십시오. –