|
|
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Больше двух лет пользуюсь вот этой замечательной библиотекой для Delphi: https://blog.grijjy.com/2017/04/25/binary-serialization-with-google-protocol-buffers/ Всё было замечательно, до позавчерашнего дня. Суть в чём. Пишу прошивку (на проклятых сях) под контроллер STM32F767, который должен общаться через TCP/IP с софтиной, писанной на Delphi с использованием вышеупомянутой библиотеки. Для реализации PB под эти ваши Си есть офигенная библиотека nanoPB, её и использую: https://jpa.kapsi.fi/nanopb/ Описание тестового .proto: авторsyntax = "proto2"; message Example { required int32 value = 1; } компилятор .proto в сишный заголовок выдаёт на выходе (только часть показываю): Код: plaintext 1. 2. 3. 4. в поле value я передаю через PB значение 540, на выходе получаю закодированное значение 089C04 онлайн-декодер правильно его декодирует в значение 540 и тип поля - varint Теперь переходим к дельфовой части описание структуры: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. На выходе получаем 270, а не 540, то есть ровно половину Если я в nanoPB закодирую любое значение, 2020, например, то дельфовый десериализатор все равно покажет ровно в два раза меньшее значение. Методом глубокого научного тыка я нашёл вариант, когда дельфя раскодирует правильно - в описании структуры TMess надо заменить тип Integer на LongWord или DWord, то есть Код: pascal 1. 2. 3. 4. 5. 6. 7. Тогда значение будет возвращаться нормально, ровно так, как его передаёт сишная часть Провёл эксперимент уже на самой дельфовой библиотеке - закодировал через неё значение 540 вариант Код: pascal 1. даёт на выходе правильное значение - 089C04 а вариант Код: pascal 1. даёт на выходе значение 08B808, которое онлайн-декодер трактует как 1080, то есть удвоенное значение - 540 * 2 = 1080 В итоге (для типа LongInt) получается следующее. NanoPB(вход 540) -> 089C04 -> Delphi(выход 270) = уполовиненное значение 540 Delphi(вход 540) -> 08B808 -> nanoPB(выход 1080) = удвоенное значение 540 В общем, вопрос в следующем - чего я не замечаю ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 11:11 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Может в порядке байт дело? На STM32 порядок байт MSB,LSB(ARM), а на Delphi(x86) LSB,MSB нужно делать Value := Swap(Value); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 11:47 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
iStrannik Может в порядке байт дело? На STM32 порядок байт MSB,LSB(ARM), а на Delphi(x86) LSB,MSB нужно делать Value := Swap(Value); PB кросс-платформенный, это не требуется в явном виде ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 12:01 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Longint это платформозависимый тип. LongWord (DWord) платформонезависимый тип ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 13:21 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator> В общем, вопрос в следующем - чего я не замечаю ? Для 0032 вместо 270 что получается? LongWord и LongInt имеют одну разрядность, там не в бобине дело, скорее всего, побитово смотри. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 13:23 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Mixrud Longint это платформозависимый тип. LongWord (DWord) платформонезависимый тип Они оба платформозависимые: http://docwiki.embarcadero.com/RADStudio/Rio/en/Simple_Types_(Delphi)#Platform-Dependent_Integer_Types ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 13:46 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator В общем, вопрос в следующем - чего я не замечаю ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 13:55 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Гаджимурадов Рустам defecator> В общем, вопрос в следующем - чего я не замечаю ? Для 0032 вместо 270 что получается? для LongInt: nanoPB(32) -> 0820 -> Delphi(16) Delphi(32) -> 0840 -> nanoPB(64) сдвиг на один бит Есть подозрение на то, что LongInt имеет знак, а LongWord его не имеет. дельфовая библиотека для PB получает информацию о полях записи через RTTI, возможно, тут где-то и порылась собака ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 14:05 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator(* Integer - не работает почему-то *) Отсюда и надо плясать. Почему не работает Integer? Явно смахивает на баг библиотеки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 14:12 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator, не работал, но может в этом? авторThe integer data types are stored in an efficient “VarInt” format. This means that smaller values are stored in less bytes than larger values. 32-bit integer types are stored in 1-5 bytes, and 64-bit integer types are stored in 1-10 bytes. Sometimes, you can have integer data that contains random values across the entire 32-bit or 64-bit range. Common examples of these are CRC or Hash values and time stamps. In those cases, it is more efficient to store these integers as fixed 32-bit or 64-bit values. You can do this by declaring the field as one of 4 fixed integer types: FixedInt32, FixedUInt32 FixedInt64, FixedUInt64 FixedInt32 - попробуй ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 14:15 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator> Есть подозрение на то, что LongInt имеет знак, а LongWord его не имеет. Подозрение? Лонгворд - беззнаковый. Перепроверь сишное обявление и код. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 14:49 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Гаджимурадов Рустам defecator> Есть подозрение на то, что LongInt имеет знак, а LongWord его не имеет. Подозрение? Лонгворд - беззнаковый. Перепроверь сишное обявление и код. я имел ввиду, что разница только в этом в сях объявлено int32, это 4-хбайтное знаковое, Longint (для x32) - тоже знаковый 4-хбайтный ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 15:19 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Zelius defecator, не работал, но может в этом? авторThe integer data types are stored in an efficient “VarInt” format. This means that smaller values are stored in less bytes than larger values. 32-bit integer types are stored in 1-5 bytes, and 64-bit integer types are stored in 1-10 bytes. Sometimes, you can have integer data that contains random values across the entire 32-bit or 64-bit range. Common examples of these are CRC or Hash values and time stamps. In those cases, it is more efficient to store these integers as fixed 32-bit or 64-bit values. You can do this by declaring the field as one of 4 fixed integer types: FixedInt32, FixedUInt32 FixedInt64, FixedUInt64 FixedInt32 - попробуй В этом случае в дельфийской библиотеке для значения 32 - 0D20000000 А с типом int32 в сишной библиотеке nanoPB сопоставить не с чем, там только int32, bytes и string ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2020, 16:12 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator, 089c04 - верное значение в wire-формате для Example с value=540 08 - маркер поля (wire type 0, номер поля 1) 9c04 - закодированное в varint целое со знаком 540 В wire-формате типов значительно меньше чем в протофайле. Для кодирования целых используется 3 типа - varint, 32-bit, 64bit. Последние 2 для fixed типов (fixed64, sfixed64, fixed32, sfixed32). Остальные, ключая bool и enum, кодируются в varint. Тут есть нюанс, кодирование отличается для знаковых и беззнаковых типов. Для беззнаковых последователность бит для кодирования берется как есть, а для знаковых оно сначала преобразеется к беззнаковому, где положительное значение как раз удваивается ( https://developers.google.com/protocol-buffers/docs/encoding#types). Поэтому важно как закодированное цело интерпретируется на принимающие стороне как знаковое или беззнаковое. По тому что ты пишешь, получается что значение декодируется как беззнаковое. Ошибка однозначно на принимающей стороне. Но где ошибка, в самой либе или в ее использовании, я хз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 07:05 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Дегтярев Евгений defecator, 089c04 - верное значение в wire-формате для Example с value=540 08 - маркер поля (wire type 0, номер поля 1) 9c04 - закодированное в varint целое со знаком 540 В wire-формате типов значительно меньше чем в протофайле. Для кодирования целых используется 3 типа - varint, 32-bit, 64bit. Последние 2 для fixed типов (fixed64, sfixed64, fixed32, sfixed32). Остальные, ключая bool и enum, кодируются в varint. Тут есть нюанс, кодирование отличается для знаковых и беззнаковых типов. Для беззнаковых последователность бит для кодирования берется как есть, а для знаковых оно сначала преобразеется к беззнаковому, где положительное значение как раз удваивается ( (подозрительная ссылка!) https://developers.google.com/protocol-buffers/docs/encoding#types). Поэтому важно как закодированное цело интерпретируется на принимающие стороне как знаковое или беззнаковое. По тому что ты пишешь, получается что значение декодируется как беззнаковое. Ошибка однозначно на принимающей стороне. Но где ошибка, в самой либе или в ее использовании, я хз. На этот нюанс со знаковыми/беззнаковыми целочисленными я решил забить для ясности. Вместо int32 на стороне nanoPB использую double - вот это однозначно и чётко ложится на тип Double в дельфи И без всяких нюансов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 13:10 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
defecator, > (подозрительная ссылка!) почему ты посчитал ссылку подозрительной? )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 14:14 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Дегтярев Евгений> почему ты посчитал ссылку подозрительной? )) Это не он, а движок форума. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 14:33 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Дегтярев Евгений почему ты посчитал ссылку подозрительной? "Быстрый ответ" нужно включить, там этого бага нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 14:37 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Гаджимурадов Рустам Это не он, а движок форума. подозрительный какой ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 16:43 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
почему ТС выбрал именно протобаф, у которого для делфи нет офф либы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 16:45 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 17:20 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Вообще этот самый протобаф не такой и сложный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 17:22 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
не увидел ссылок на него на странице протобафа отсюда и заявление про отсутствие официальной либы зы почему половина ссылок которые я тут вижу sourceforge.net ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 20:41 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
Для него, кстати, и генератор есть: https://github.com/kami-soft/ProtoBufGenerator ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2020, 21:41 |
|
||
|
Кто работал с Google Protocol Buffers ? Есть вопрос !
|
|||
|---|---|---|---|
|
#18+
zedxxx Для него, кстати, и генератор есть: https://github.com/kami-soft/ProtoBufGenerator для библиотеки, которую я использую, и на которую ссылка в первом посте, https://blog.grijjy.com/2017/04/25/binary-serialization-with-google-protocol-buffers/ никакой генератор не нужен вообще. всё начинается и заканчивается объявлением record'а прямо в коде программы - и вот этим библиотека просто замечательна ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.10.2020, 15:28 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=40007117&tid=2037940]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
176ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
| others: | 236ms |
| total: | 514ms |

| 0 / 0 |
