2017-02-01 7 views
1

У меня есть сообщение Protobuf похожего на это:установки повторного поля в Protobuf с помощью отражения

message foo { 
    repeated double values = 1; 
} 

Я использую отражение (как объяснен here), чтобы установить значение, как это в моем C++ код

auto desc = protoMsg.GetDescription(); 
auto refl = protoMsg.GetReflection(); 
auto fd = desc->FindFieldByNumber(1); // run time value 

assert(fd->is_repeated()); 
for (int i = 0; i < vect.size(); ++i) 
    refl->SetRepeatedDouble(&protoMsg, fd, i, vect[i]); 

Мое заявление сбой внутри SetRepeatedDouble функция. Кто-нибудь пытался сделать что-то подобное раньше? (задайте значения с помощью отражения?) Обратите внимание, что я должен использовать отражение из-за динамической природы моего приложения. Я упростил код выше, чтобы этого не сделать на данный момент)

Также предлагаются советы по возможности отладки.

ответ

2

SetRepeatedDouble() перезаписывает уже существующий элемент массива. Для того, чтобы ваш код работал, повторное поле должно иметь размер как минимум равный vect.size(), в противном случае вы превысите массив, что действительно вызовет крах (или, что еще хуже). Если вы начали с пустым экземпляром сообщения, то вам нужно добавить значения вместо того, чтобы устанавливать их, например, так:

for (int i = 0; i < vect.size(); ++i) 
    refl->AddDouble(&protoMsg, fd, vect[i]); 
+0

Спасибо! Это немного неинтуитивно. В документах говорится примерно так: - Возможные источники ошибок: - Метод Get *() или Set *() для особых полей вызывается в повторном поле. - GetRepeated *(), SetRepeated *() или Add *() вызывается в не повторяющемся поле. – skgbanga