Страница 1 из 1

Flatten To String баг или фича?

Добавлено: 11 сен 2017, 18:15
Juri
На вход подаем кластер с пустым массивом или кластер с пустой строкой. На выходе получаем какие-то левые 4 байта. Как так то? Можно вылечить?

upd: решение - http://labviewportal.org/viewtopic.php? ... 195#p76195

Re: Flatten To String баг или фича?

Добавлено: 11 сен 2017, 18:38
dadreamer
Usss писал(а):какие-то левые 4 байта
Это размер массива.

Код: Выделить всё

typedef struct {
	int32 dimSize;
	uInt8 Numeric[1];
	} TD2;
typedef TD2 **TD2Hdl;

typedef struct {
	TD2Hdl Array;
	} TD1;
How LabVIEW Stores Data in Memory
Flattened Data
Usss писал(а):Можно вылечить?
В виде кластера - нет. В виде массива - вход prepend array or string size? А что конкретно требуется?

Re: Flatten To String баг или фича?

Добавлено: 12 сен 2017, 10:32
Juri
Требуется преобразовать кластер в массив байт. Кластеров много разных, содержимое у каждого свое, в том числе числа, массивы и строки. Пока не придумал ничего лучше чем преобразовывать каждый элемент кластера отдельно

Re: Flatten To String баг или фича?

Добавлено: 12 сен 2017, 10:53
dadreamer
Usss писал(а):массивы и строки
Из-за того, что :labview: хранит массивы и строки иначе, чем это делают многие текстовые среды, кластер с массивами и/или строками придётся разбирать поэлементно. И это, похоже, единственный способ: https://forums.ni.com/t5/LabVIEW/What-i ... -p/3175307 Ну, то есть, либо вы делаете то же, что и сейчас, либо вы преобразуете ваши кластеры так, чтобы они не содержали нативные массивы/строки :labview: , а вместо них содержали фиксированные по длине (числу байтов) кластеры из элементов U8, которые и будут представлять собой массив или строку в привычной нотации. Если используете TypeDef'ы, то это требуется сделать один раз. Есть, правда, и минус у последнего подхода - ухудшается читаемость содержимого кластеров.

Re: Flatten To String баг или фича?

Добавлено: 12 сен 2017, 11:48
AndreyDmitriev
Usss писал(а):Требуется преобразовать кластер в массив байт. Кластеров много разных, содержимое у каждого свое, в том числе числа, массивы и строки. Пока не придумал ничего лучше чем преобразовывать каждый элемент кластера отдельно
Это не то чтобы баг, просто при использовании Flatten To String предполагается, что вы будете восстанавливать данные обратно из строки используя Unflatten From String. Если вы подсоединяете на вход "чистый" массив или строку, то в этом случае информация о длине избыточна - вы можете управлять добавлением четырёх байтов длины, используя ключ prepend array or string size? (T) и data includes array or string size? (T) в этих элементах. Однако ситуация меняется, если используется кластер - в него вы можете положить две строки или два массива и в этом случае без информации о том, где заканчивается один массив или строка и начинается другой восстановление из строки станет невозможным, поэтому LabVIEW и добавляет четыре байта длины независимо от установленного переключателя "prepend array or string size?". Если вам эти четыре байта "мешают", то это говорит о том, что вы используете свой собственный формат данных, ну соответственно и сериализатор должен быть свой, что вы собственно и реализовали поэлементным преобразованием.
Why does a String in a Cluster have Four Extra Bytes?
http://digital.ni.com/public.nsf/allkb/ ... 32005C5B14

Re: Flatten To String баг или фича?

Добавлено: 15 сен 2017, 17:47
Juri
Решено!
Было ощущение, что изобретаю велосипед. Не понятно, почему такой vi нет по умолчанию в LV.
Я разобрал только нужные мне типы: все integer, Uinteger, double, массивы из этих типов, кластеры, массив кластеров. Если кому, нужны остальные типы, тот без труда дополнит.

Re: Flatten To String баг или фича?

Добавлено: 15 сен 2017, 18:54
dadreamer
Usss писал(а):Не понятно, почему такой vi нет по умолчанию в LV.
Ну, потому что такой функционал уже присутствует, хотя для вашей задачи он даёт избыточный результат. Речь о Flatten To String, само собой. В большинстве случаев достаточно было бы модифицировать собственные структуры данных, чтобы они учитывали или включали в себя длину/размер массивов и строк, предваряющий этот массив (строку). У вас, видимо, иной случай. Вообще, и во внешний код :labview: отправляет кластеры так, как сам их хранит, предоставляя программисту самому разбирать элементы. Правда, там ещё чуть сложнее получается - вместо массивов приходят указатели на них. Естественно, длина массива предваряет данные.

Re: Flatten To String баг или фича?

Добавлено: 15 сен 2017, 19:41
Juri
Вот щас ваще красоту навел. На самом деле мне надо эти данные передавать по TCP, принимающая сторона имеет протокол данных и сможет их расшифровать. Так что мне совсем не нравится что Flatten To String передает всякие мета данные

Re: Flatten To String баг или фича?

Добавлено: 15 сен 2017, 21:43
Kosist
Usss писал(а):Вот щас ваще красоту навел. На самом деле мне надо эти данные передавать по TCP, принимающая сторона имеет протокол данных и сможет их расшифровать. Так что мне совсем не нравится что Flatten To String передает всякие мета данные
Конвертируйте все в JSON строку (либа от JKI прекрасно с этим справляется), и пусть принимающая сторона ее обрабатывает. Универсальный формат, все как надо :wink: И нет лишних мета данных - лишь параметры, и их значения.

Re: Flatten To String баг или фича?

Добавлено: 15 сен 2017, 22:37
Borjomy_1
Вообще-то flatten To string это чемпион по компактности. И ежели у вас размер массива фиксированный, то обычно делают кластер с заданным количеством элементов. Передавать динамический массив без размера - глупость. Если размер массива находится не перед ним в посылке, то совершенно не возбраняется закидывать элементы в строку раздельно, а потом их собрать в одну строку. И разбор можно делать также, последовательно.

Re: Flatten To String баг или фича?

Добавлено: 16 сен 2017, 00:07
Kosist
Borjomy_1 писал(а):Вообще-то flatten To string это чемпион по компактности. И ежели у вас размер массива фиксированный, то обычно делают кластер с заданным количеством элементов. Передавать динамический массив без размера - глупость. Если размер массива находится не перед ним в посылке, то совершенно не возбраняется закидывать элементы в строку раздельно, а потом их собрать в одну строку. И разбор можно делать также, последовательно.
TCP/IP само по себе уже должно обеспечивать целостность передаваемых данных, т.е. при передаче сообщений (конечно, если "разумных" размеров), можно не проверять ее целостность, или размер. Если данных реально много, то тогда без склеивания не обойтись... Но это уже смахивает на собственный протокол, если посылка может разбиваться на части при передаче, собираться при приеме; а все это будет контролироваться проверочными суммами, и т.д.
Используя Network Streams можно вообще не париться, а передавать, скажем, кластер с именем/типом пакета, и вариантом для данных - и запихивать туда все, что угодно. Главное, знать как парсить...
Для более высокого уровня коммуникации - как мне кажется - этот момент можно опустить...
Недавно столкнулся с MQTT протоколом для "общения" с "облаком". На низком уровне данные передаются посредством TCP/IP - там идет преобразование в массив байтов, контролируется размер сообщения, и т.д. Но на "высшем" уровне уже есть просто JSON строка, которая содержит данные...
Но согласен, что следуя Вашему совету можно быть уверенным, что все данные не потеряются, и будут целостными. Но экстра работы добавится... Поэтому опять же, почему не использовать те же вышеупомянутые Network Streams, если они уже содержат нужный функционал? (при условии, что получателем будет тоже :labview: приложение...).

Re: Flatten To String баг или фича?

Добавлено: 16 сен 2017, 12:37
dadreamer
Usss писал(а):На самом деле мне надо эти данные передавать по TCP, принимающая сторона имеет протокол данных и сможет их расшифровать.
А мне вдруг стало интересно, как всё-таки принимающая сторона будет расшифровывать динамический массив, если нигде нет его размера? А если все массивы имеют фиксированные размеры, тогда не было смысла изобретать велосипед. Даже если учесть, что принимающая сторона имела бы "устаканившийся" протокол, который она не могла или не хотела бы менять.

Re: Flatten To String баг или фича?

Добавлено: 16 сен 2017, 12:51
Juri
Длина данных от пользователя к серверу всегда известна, а длина данных от сервера к пользователю вычисляется исходя из параметров, которые пользователь ему отправляет. ПО сервера написано не на LAbview, но его позже тоже надо будет переписать на Labview

Re: Flatten To String баг или фича?

Добавлено: 16 сен 2017, 14:39
Blackman
...Было ощущение, что изобретаю велосипед....

Re: Flatten To String баг или фича?

Добавлено: 16 сен 2017, 22:12
dadreamer
Хотя при первом взгляде кажется, что решение Usss выглядит малость "велосипедно", что-то в нём есть. Если представить, что есть превеликое множество кластеров с совершенно различными типами данных в них, включая вложенные кластеры, то конвертация в поток байтов может быть изрядным "гемором" - каждый кластер надо разобрать на элементы, каждый элемент прогнать через Type Cast, затем все эти выходы объединить в одно целое. Это займёт ощутимое время и не менее ощутимое место на БД. ВИ-айка Usss практически могла бы обеспечить компактность на диаграмме и простоту преобразования, а также универсальность, что немаловажно. Другое дело, что её потребуется допилить, чтобы она "ела" все возможные типы данных :labview: . Ну, и нельзя не заметить, что случай, когда потребуется подобное преобразование без "левых" данных, может вовсе не представиться. На мой практике я припоминаю ровно один такой случай - нужно было преобразовать несколько кластеров в массив U8 для отправки через Profinet плату. Мне было проще разобрать кластеры, благо что их было не более 5 штук.