powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Кто работал с Google Protocol Buffers ? Есть вопрос !
25 сообщений из 31, страница 1 из 2
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006497
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Больше двух лет пользуюсь вот этой замечательной библиотекой для 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.
/* Struct definitions */
typedef struct _Example {
    int32_t value;
} Example;



в поле value я передаю через PB значение 540, на выходе получаю закодированное значение 089C04
онлайн-декодер правильно его декодирует в значение 540 и тип поля - varint

Теперь переходим к дельфовой части

описание структуры:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
type
    TMess = record
    public
      [Serialize(1)] value : LongInt ; 
    public
      procedure Initialize ;
    end ;

var
   InArr : TBytes ;
   Rec : TMess ;
begin
     InArr := [$08, $9C, $04] ;
     TgoProtocolBuffer.Deserialize(TypeInfo(TMess), Rec, @InArr[0], Length(InArr)) ;
end ;



На выходе получаем 270, а не 540, то есть ровно половину
Если я в nanoPB закодирую любое значение, 2020, например, то дельфовый десериализатор все равно покажет ровно в два раза меньшее значение.

Методом глубокого научного тыка я нашёл вариант,
когда дельфя раскодирует правильно - в описании структуры TMess надо заменить тип Integer на LongWord или DWord,
то есть

Код: pascal
1.
2.
3.
4.
5.
6.
7.
type
    TMess = record
    public
      [Serialize(1)] value : LongWord ; (* Integer - не работает почему-то *)
    public
      procedure Initialize ;
    end ;


Тогда значение будет возвращаться нормально, ровно так, как его передаёт сишная часть

Провёл эксперимент уже на самой дельфовой библиотеке - закодировал через неё значение 540

вариант
Код: pascal
1.
value : LongWord ;


даёт на выходе правильное значение - 089C04

а вариант
Код: pascal
1.
value : LongInt ;


даёт на выходе значение 08B808, которое онлайн-декодер трактует как 1080, то есть удвоенное значение - 540 * 2 = 1080

В итоге (для типа LongInt) получается следующее.
NanoPB(вход 540) -> 089C04 -> Delphi(выход 270) = уполовиненное значение 540
Delphi(вход 540) -> 08B808 -> nanoPB(выход 1080) = удвоенное значение 540

В общем, вопрос в следующем - чего я не замечаю ?
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006518
iStrannik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может в порядке байт дело?
На STM32 порядок байт MSB,LSB(ARM), а на Delphi(x86) LSB,MSB нужно делать Value := Swap(Value);
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006530
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
iStrannik
Может в порядке байт дело?
На STM32 порядок байт MSB,LSB(ARM), а на Delphi(x86) LSB,MSB нужно делать Value := Swap(Value);


PB кросс-платформенный, это не требуется в явном виде
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006558
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Longint это платформозависимый тип.
LongWord (DWord) платформонезависимый тип
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006560
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator> В общем, вопрос в следующем - чего я не замечаю ?

Для 0032 вместо 270 что получается?

LongWord и LongInt имеют одну разрядность, там
не в бобине дело, скорее всего, побитово смотри.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006575
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud
Longint это платформозависимый тип.
LongWord (DWord) платформонезависимый тип

Они оба платформозависимые: http://docwiki.embarcadero.com/RADStudio/Rio/en/Simple_Types_(Delphi)#Platform-Dependent_Integer_Types
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006576
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator
В общем, вопрос в следующем - чего я не замечаю ?
Может там где-то используется сдвиг разрядов с учетом знака (SAR/SAL)?
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006579
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Гаджимурадов Рустам
defecator> В общем, вопрос в следующем - чего я не замечаю ?

Для 0032 вместо 270 что получается?


для LongInt:
nanoPB(32) -> 0820 -> Delphi(16)
Delphi(32) -> 0840 -> nanoPB(64)

сдвиг на один бит

Есть подозрение на то, что LongInt имеет знак, а LongWord его не имеет.

дельфовая библиотека для PB получает информацию о полях записи через RTTI,
возможно, тут где-то и порылась собака
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006584
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
defecator(* Integer - не работает почему-то *)
Отсюда и надо плясать. Почему не работает Integer? Явно смахивает на баг библиотеки.
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006586
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 - попробуй
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006595
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator> Есть подозрение на то, что LongInt имеет знак, а LongWord его не имеет.

Подозрение? Лонгворд - беззнаковый.
Перепроверь сишное обявление и код.


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006605
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Гаджимурадов Рустам
defecator> Есть подозрение на то, что LongInt имеет знак, а LongWord его не имеет.

Подозрение? Лонгворд - беззнаковый.
Перепроверь сишное обявление и код.


я имел ввиду, что разница только в этом

в сях объявлено int32, это 4-хбайтное знаковое, Longint (для x32) - тоже знаковый 4-хбайтный
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006617
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
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
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006791
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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). Поэтому важно как закодированное цело интерпретируется на принимающие стороне как знаковое или беззнаковое.

По тому что ты пишешь, получается что значение декодируется как беззнаковое. Ошибка однозначно на принимающей стороне. Но где ошибка, в самой либе или в ее использовании, я хз.
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006906
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Дегтярев Евгений
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 в дельфи
И без всяких нюансов.
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006945
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator,

> (подозрительная ссылка!)

почему ты посчитал ссылку подозрительной? ))
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006956
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений> почему ты посчитал ссылку подозрительной? ))

Это не он, а движок форума.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40006959
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений
почему ты посчитал ссылку подозрительной?
Это движок 22108475 , judge не поправил.
"Быстрый ответ" нужно включить, там этого бага нет.
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007021
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам
Это не он, а движок форума.

подозрительный какой
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007024
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
почему ТС выбрал именно протобаф, у которого для делфи нет офф либы?
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007032
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007034
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще этот самый протобаф не такой и сложный.
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007117
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник

не увидел ссылок на него на странице протобафа отсюда и заявление про отсутствие официальной либы

зы
почему половина ссылок которые я тут вижу sourceforge.net ?
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007139
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость

Для него, кстати, и генератор есть: https://github.com/kami-soft/ProtoBufGenerator
...
Рейтинг: 0 / 0
Кто работал с Google Protocol Buffers ? Есть вопрос !
    #40007250
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
zedxxx

Для него, кстати, и генератор есть: https://github.com/kami-soft/ProtoBufGenerator


для библиотеки, которую я использую, и на которую ссылка в первом посте,
https://blog.grijjy.com/2017/04/25/binary-serialization-with-google-protocol-buffers/
никакой генератор не нужен вообще.

всё начинается и заканчивается объявлением record'а прямо в коде программы - и вот этим библиотека просто замечательна
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Кто работал с Google Protocol Buffers ? Есть вопрос !
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]