2014-10-16 3 views
0

У меня есть протокол протокол Буферы определяется следующим образом:протокол расширенного буфера не распознается на OSX

package pkg; 

message Query { 
    optional uint32 basicfield = 1; 

    extensions 100 to max; 
} 

message Point { 
    optional int32 x = 1; 
    optional int32 y = 2; 
} 

message SpecificQuery { 
    oneof specific_oneof { 
     Point centre = 1000; 
     Point corner = 2000; 
    } 

    extend pkg.Query { 
     optional SpecificQuery specific_query = 101; 
    } 
} 

Я использую протокол Буфера 2.6.1rc1 (и я также протестировал с 2.6.0), так как я хочу попытаться использовать функцию oneof. Все это 64-битный C++. make check проходит на обеих платформах. Если я отправлю и получаю как в Linux (компиляция с gcc 4.6.3), он работает нормально. Если я получаю один Mac (OSX 10.9, компиляция с Clang под XCode), однако, похоже, он не распознает расширения.

Это принимающий код:

if (query.ParseFromArray(array, len)) 
{ 
    if (query.has_basicfield()) 
    { 
     printf("Basicfield: %d", query.basicfield()); 
    } 

    if (query.HasExtension(pkg::SpecificQuery::specific_query)) 
    { 
     // Never reached on OSX 
     // Reached on Linux 
     pkg::SpecificQuery* sqy = query.MutableExtension(pkg::SpecificQuery::specific_query); 

      if (sqy && sqy->specific_oneof_case() == pkg::SpecificQuery::kcentre) 
      { 
       // Also reached on linux 
      } 
    } 
} 

Если я печатаю объект протокола буфера с PrintDebugString(), я получаю это, как ожидается, на Linux:

basicfield: 1234 
[pkg.SpecificQuery.specific_query] { 
    centre { 
    x: 50 
    y: 150 
    } 
} 

Но на Mac, я вижу :

basicfield: 1234 
101 { 
    1000 { 
    1: 50 
    2: 150 
    } 
} 

кроме того, query._extensions_ пуст, но query._unknown_fields_ со netss 101, указывая, что реестр расширения, похоже, не работает. Кто-нибудь знает, почему?

ответ

2

Какое-то определение SpecificQuery::specific_query не связано в вашем приложении. Возможно, ваш компилятор настолько умен, что ему удалось оптимизировать все вызовы, сделанные вами на protobuf, и ваш компоновщик настолько умен, что ему удалось удалить весь объектный файл из вашей выходной программы. Если вы .pb.o каким-то образом не связаны в программе, то его инициализаторы никогда не будут запускаться, поэтому любые расширения, которые он определяет, никогда не будут зарегистрированы, и вы увидите поведение, которое видите.

Один из способов заставить связь является размещением фиктивного использования внутри какого-либо другого кода, который вы знаете, является получение должным образом связан, например, вы можете добавить эту строку в функцию вы публикуемая:.

SpecificQuery::default_instance(); 

Этого вызов функции не имеет побочного эффекта, но реализован в файле .pb.cc и, таким образом, заставит связать .pb.o.

+0

Это была проблема связи, но это было связано с тем, что мне удалось получить protobuf-lite dylib, связанный моим проектом XCode, в дополнение к нормальному протобуфу, который, очевидно, использовался в предпочтении! – Inductiveload

Смежные вопросы