Как упаковать переменые разных типов в один byte[]
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 29.06.02 19:00
Оценка: 62 (3)
#Имя: FAQ.dotnet.pack2byte[]
Здравствуйте Vyacheslav_M, Вы писали:

VM>Привет всем!


VM>Есть следующая задача:


VM>есть переменная

VM>int var;

VM>структура

VM>private struct s
VM>{
VM> public bool Move;
VM> public int xPos;
VM> public int yPos;
VM>}
VM>s tmp;

VM>и массив байтов

VM>byte[]=new byte[n];

VM>дак вот, надо эту переменную, структуру и массив байтов запихать в другой массив байтов

VM>что бы отправить в socket а на клиентской стороне все это вытащить из того же массива байтов.
VM>Как все это организовать без указателей?

Ну для int и byte[] все просто
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
br.Write(var);
br.Write(bytearr);
socket.Send(ms.Buffer);


Для классов и структур все немножко посложнее
//Твою структурку надо пометить как сериализуемую
[Serializable]
private struct s {
 public bool Move;
 public int xPos;
 public int yPos;
}

...

//Ну а далее выбираешь сериализатор и вперед

MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);

IFormatter formatter = new BinaryFormatter();

br.Write(var);
formatter.Serialize(ms,s);
br.Write(bytearr);
socket.Send(ms.Buffer);
AVK Blog
Re[3]: пара вопросов в тему
От: TK Лес кывт.рф
Дата: 15.06.03 09:07
Оценка: 14 (3)
Hello, "Ed.ward"
>
> А по другому (но стандартными средствами) никак? А то у меня структура с единственным Int32 полем в сеарилизованном состоянии заняла 165! байт.
>

Надо имя структуры по короче сделать. Или можно использовать яву классы — там примерно в 1.5 раза компактнее

using System;

namespace SerializationTest
{
 [Serializable]
 public struct CSStruct 
 {
  public int csValue;
 }

 public struct JSStruct : java.io.Serializable
 {
  public int jsValue;
 }

 class TestConsole
 {
  [STAThread]
  static void Main(string[] args)
  {
   SerializeCS();
   SerializeJS();
  }

  static void SerializeJS()
  {
   java.io.ByteArrayOutputStream stm;
   java.io.ObjectOutputStream objectStm;

   stm = new java.io.ByteArrayOutputStream();
   objectStm = new java.io.ObjectOutputStream(stm);

   objectStm.writeObject(new JSStruct());

   Console.WriteLine("Java Serialization (SimpleStruct): {0}", stm.size());

   stm = new java.io.ByteArrayOutputStream();
   objectStm = new java.io.ObjectOutputStream(stm);
   
   java.util.ArrayList list = new java.util.ArrayList();

   for (int i = 0 ; i < 10 ; ++i) {
    list.add(new JSStruct());
   }

   objectStm.writeObject(list);
   Console.WriteLine("Java Serialization (ArrayList): {0}", stm.size());
  }

  static void SerializeCS()
  {
   System.IO.MemoryStream stm;
   
   using (stm = new System.IO.MemoryStream())
   {
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

    formatter.Serialize(stm, new CSStruct());
    Console.WriteLine(".NET Serialization (SimpleStruct): {0}", stm.Length);
   }

   using (stm = new System.IO.MemoryStream())
   {
    System.Collections.ArrayList list = new System.Collections.ArrayList();
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

    for (int i = 0 ; i < 10 ; ++i) {
     list.Add(new CSStruct());
    }

    formatter.Serialize(stm, list);
    Console.WriteLine(".NET Serialization (ArrayList): {0}", stm.Length);
   }
  }
 }
}


> И еще вопрос про Remoting, он только по TCP/IP умеет ходить, или можно к другим протоколам привязать?

>

NamedPipes, MSMQ, MSNMessenger, Jabber, SMTP, HTTP, CORBA, MemoryMappedFiles и еще что-нибудь...
Искать: BidirectionalTCPChannel.zip, jabberchannel.zip, MSMQChannel_src.zip, NamedPipeChannel.zip, smtpchannel.zip
Posted via RSDN NNTP Server 1.6 beta
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: Как это можно сделать в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.06.03 08:10
Оценка: 6 (1)
Здравствуйте, Ed.ward, Вы писали:

AVK>>Нет, маршалер вполне managed. Просто ты можешь столкнуться с тем что после очередной версии у тебя старые данные перестанут работать.


EW>Marshals data from a managed object to an unmanaged block of memory.


Ну и что? unmanaged block of memory можно выделить из managed кода тем же маршаллером.
... << RSDN@Home 1.1 alpha 1 >>
AVK Blog
Re[3]: Как это можно сделать в C#?
От: TK Лес кывт.рф
Дата: 29.06.02 21:17
Оценка: 3 (1)
Здравствуйте Vyacheslav_M, Вы писали:

VM>Здравствуйте AndrewVK, Вы писали:



VM>а как записать в MemoryStream переменную типа перечисление?


Например через тот-же Formatter...
Или определить базовый тип перечисления (System.Enum.GetUnderlyingType()) и записать его.
Или преобразовать enum в строку и записать ее
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[3]: пара вопросов в тему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.06.03 06:42
Оценка: 2 (1)
Здравствуйте, Ed.ward, Вы писали:

EW>И еще вопрос про Remoting, он только по TCP/IP умеет ходить, или можно к другим протоколам привязать?


Умеет, если соотв. ченнел есть.
... << RSDN@Home 1.1 alpha 1 (np: тихо) >>
AVK Blog
Re[2]: Как это можно сделать в C#?
От: mihailik Украина  
Дата: 17.06.03 15:28
Оценка: 2 (1)
AVK>Для классов и структур все немножко посложнее
AVK>
AVK>//Твою структурку надо пометить как сериализуемую
AVK>...

AVK>//Ну а далее выбираешь сериализатор и вперед
AVK>


Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.
... << RSDN@Home 1.0 beta 7a >>
Re: Binary(Writer/Reader)
От: mihailik Украина  
Дата: 19.06.03 08:04
Оценка: 2 (1)
EW>Угу
EW>Только, по-моему, проще опираться сразу на Binary(Writer/Reader)

Тогда советую посмотреть на gotdotnet.com BinaryObjectWriter. Что-то среднее между сериализацией и Marshal.

Структуру можно разметить атрибутами, по ним этот BinaryObjectWriter её может читать и писать в поток байтов.

Метаданные, как и в способе с Marshal не пишутся, поэтому объём экономится. Но если структура поменяется — автоматически прочитать из старых данных не сможет.

Этот способ будет тормознее Marshal, но безопаснее.
... << RSDN@Home 1.0 beta 7a >>
Re[5]: Binary(Writer/Reader)
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 21:23
Оценка: 1 (1)
Здравствуйте, mihailik, Вы писали:

M>Ну так посмотри, как BinaryReader/Writer устроен. И переделай.


Зачем переделывать? Только написать обертку которая будет писть строки чуть по другому.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Как это можно сделать в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.07.02 05:21
Оценка: -1
Здравствуйте Vyacheslav_M, Вы писали:

VM>Здравствуйте VladD2, Вы писали:


VD>>А может человеку лучше о ремоутенге почитать? Все же вручную с сокетами это мазахизм, тем более что имеется такой развитой механизм как ремоутинг...


VM>А что это такое и с чем его едят???


Это механизм взаимодействия удаленных объектов.
AVK Blog
Re[8]: Как это можно сделать в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.06.03 05:36
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>А зачем? Почему просто BinaryWriter-ром не записать все поля? Там полей-то...


Это если какую нибудь конкретную структуру. А если любую? Через рефлекшен?
... << RSDN@Home 1.1 alpha 1 >>
AVK Blog
Re[5]: Как это можно сделать в C#?
От: Nick Notabene Россия  
Дата: 20.06.03 16:21
Оценка: -1
... Skipped
Гы. Читаю я эту нитку и кажется мне что лечение много хуже болезни...
Ed.ward, у тебя и отправитель и получатель знают формат структуры и буфера ?
Зачем тогда весь этот многопудовый геморрой ???


M>Кто такой, почему не знаю?


Есть такая фунция send, в ws2_32.dll Если уж необходимо делать все на С#, то [DllImport] ваше спасение...

Прав был Оккам, сто раз прав, и неудержимый рост глюкавых приложений под .Net наглядное тому подтверждение...

Гы.
Интуитивно понятный интерфейс — это интерфейс, для работы с которым нужна недюжинная интуиция...
Re[6]: Как это можно сделать в C#?
От: Gollum Россия  
Дата: 21.06.03 05:51
Оценка: +1
Здравствуйте, Nick Notabene, Вы писали:

M>>Кто такой, почему не знаю?


NN>Есть такая фунция send, в ws2_32.dll Если уж необходимо делать все на С#, то [DllImport] ваше спасение...


using System.Net.Sockets;

Sockуt sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
// ... connecting or anyway

sock.Send(/* blabla */);


NN>Прав был Оккам, сто раз прав, и неудержимый рост глючных приложенийпод .Net наглядное тому подтверждение...


Точно, прав Я воздержусь от высказываний про глючные приложения под апи
... << RSDN@Home 1.0 beta 6a >>
Eugene Agafonov on the .NET

Re[7]: Как это можно сделать в C#?
От: Nick Notabene Россия  
Дата: 21.06.03 07:40
Оценка: :)
Здравствуйте, Gollum, Вы писали:

G>
G>using System.Net.Sockets;

G>Sockуt sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
G>// ... connecting or anyway

G>sock.Send(/* blabla */);
G>


Угу. По идее, вызывается тот же ws2_32.dll. Но ради бога, объясните мне, почему при передаче бинарных данных элементарной программкой на VC6 загрузка сети 3%, процессора — 5 %, а при Socket.Send — 9% и 12% соответсвтенно ? Одни и те же данные, один и тот же алгоритм...

G>Точно, прав Я воздержусь от высказываний про глючные приложения под апи


RSDN написан на .Net как я понимаю ? Откуда три и два сообщения там, где отправлялось по одному ???
Вчера два раза посмотрел на заставку "invalid input string",и все дела.

.Net помимо потери производительности, статистически неустоцчив. Если алгоритм сработал 99 раз, нет никакой гарантии, что в 100 раз он сработает так же. Любой, даже самый простой алгоритм, использующий System.Net , System.Runtime, становится нестабильным и непредсказуемым.
Интуитивно понятный интерфейс — это интерфейс, для работы с которым нужна недюжинная интуиция...
Как это можно сделать в C#?
От: Vyacheslav_M  
Дата: 29.06.02 18:42
Оценка:
Привет всем!

Есть следующая задача:

есть переменная
int var;

структура
private struct s
{
public bool Move;
public int xPos;
public int yPos;
}
s tmp;

и массив байтов
byte[]=new byte[n];

дак вот, надо эту переменную, структуру и массив байтов запихать в другой массив байтов
что бы отправить в socket а на клиентской стороне все это вытащить из того же массива байтов.
Как все это организовать без указателей?
Re[2]: Как это можно сделать в C#?
От: Vyacheslav_M  
Дата: 29.06.02 19:36
Оценка:
Здравствуйте AndrewVK, Вы писали:


AVK>Ну для int и byte[] все просто

AVK>
AVK>MemoryStream ms = new MemoryStream();
AVK>BinaryWriter bw = new BinaryWriter(ms);
AVK>br.Write(var);
AVK>br.Write(bytearr);
AVK>socket.Send(ms.Buffer);
AVK>


AVK>Для классов и структур все немножко посложнее

AVK>
AVK>//Твою структурку надо пометить как сериализуемую
AVK>[Serializable]
AVK>private struct s {
AVK> public bool Move;
AVK> public int xPos;
AVK> public int yPos;
AVK>}

AVK>...

AVK>//Ну а далее выбираешь сериализатор и вперед

AVK>MemoryStream ms = new MemoryStream();
AVK>BinaryWriter bw = new BinaryWriter(ms);

AVK>IFormatter formatter = new BinaryFormatter();

AVK>br.Write(var);
AVK>formatter.Serialize(ms,s);
AVK>br.Write(bytearr);
AVK>socket.Send(ms.Buffer);

AVK>


а как записать в MemoryStream переменную типа перечисление?
Re[3]: Как это можно сделать в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 30.06.02 05:05
Оценка:
Здравствуйте Vyacheslav_M, Вы писали:

VM>а как записать в MemoryStream переменную типа перечисление?

А перечисление это на самом деле целое.

An enum declaration may explicitly declare an underlying type of byte, sbyte, short, ushort, int, uint, long or ulong

так что можешь явно указать подлежащий для перечисления тип.

Ну а потом как обычно пишешь BinaryWriter
AVK Blog
Re[2]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.06.02 17:19
Оценка:
Здравствуйте AndrewVK, Вы писали:

А может человеку лучше о ремоутенге почитать? Все же вручную с сокетами это мазахизм, тем более что имеется такой развитой механизм как ремоутинг...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Как это можно сделать в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 30.06.02 18:35
Оценка:
Здравствуйте VladD2, Вы писали:

VD>А может человеку лучше о ремоутенге почитать? Все же вручную с сокетами это мазахизм, тем более что имеется такой развитой механизм как ремоутинг...

Может быть. А может и нет. Он же как обычно не сказал подробно что хочет. Может там вобще ничего пересылать не нужно. А может структуру в каком то особенном формате пересылать надо. Тут можно только гадать.
AVK Blog
Re[3]: Как это можно сделать в C#?
От: Vyacheslav_M  
Дата: 04.07.02 03:10
Оценка:
Здравствуйте VladD2, Вы писали:

VD>А может человеку лучше о ремоутенге почитать? Все же вручную с сокетами это мазахизм, тем более что имеется такой развитой механизм как ремоутинг...


А что это такое и с чем его едят???
Re[2]: пара вопросов в тему
От: Ed.ward Россия  
Дата: 15.06.03 01:00
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Для классов и структур все немножко посложнее

AVK>
AVK>//Твою структурку надо пометить как сериализуемую
AVK>[Serializable]
AVK>private struct s {
AVK> public bool Move;
AVK> public int xPos;
AVK> public int yPos;
AVK>}

AVK>...

AVK>//Ну а далее выбираешь сериализатор и вперед

AVK>MemoryStream ms = new MemoryStream();
AVK>BinaryWriter bw = new BinaryWriter(ms);

AVK>IFormatter formatter = new BinaryFormatter();

AVK>br.Write(var);
AVK>formatter.Serialize(ms,s);
AVK>br.Write(bytearr);
AVK>socket.Send(ms.Buffer);

AVK>


А по другому (но стандартными средствами) никак? А то у меня структура с единственным Int32 полем в сеарилизованном состоянии заняла 165! байт.

И еще вопрос про Remoting, он только по TCP/IP умеет ходить, или можно к другим протоколам привязать?

Ed.ward
Re[4]: пара вопросов в тему
От: Ed.ward Россия  
Дата: 16.06.03 08:29
Оценка:
Здравствуйте, TK, Вы писали:


TK>Надо имя структуры по короче сделать. Или можно использовать яву классы — там примерно в 1.5 раза компактнее


Короче некуда "AddLines"...

Ed.ward
Re[3]: пара вопросов в тему
От: Vadim B  
Дата: 17.06.03 15:47
Оценка:
Здравствуйте, Ed.ward, Вы писали:

EW>А по другому (но стандартными средствами) никак? А то у меня структура с единственным Int32 полем в сеарилизованном состоянии заняла 165! байт.


Если тебе единственное поле надо переслать, или если надо переслать в виде потока байтов определенного формата (чтобы другая программа не на дотнете понимала, например), то посмотри в сторону System.BitConverter.GetBytes(). Обратное преобразование — System.BitConverter.ToInt32().

EW>И еще вопрос про Remoting, он только по TCP/IP умеет ходить, или можно к другим протоколам привязать?


Можно к чему угодно привязать, но возни будет очень много. Инго Раммер в своей книге, например, приводит реализацию ремоутинга через е-мэйлы (при вызове функции серверу посылается е-мэйл, он отвечает е-мэйлом с результатом).
Re[4]: пара вопросов в тему
От: TK Лес кывт.рф
Дата: 17.06.03 18:44
Оценка:
Hello, "Vadim B"

> EW>И еще вопрос про Remoting, он только по TCP/IP умеет ходить, или можно к другим протоколам привязать?

>
> Можно к чему угодно привязать, но возни будет очень много. Инго Раммер в своей книге, например, приводит реализацию ремоутинга через е-мэйлы (при вызове функции серверу посылается е-мэйл, он отвечает е-мэйлом с результатом).

Не он первый это придумал. В Technology Preview для .NET Framework и не такое было
Posted via RSDN NNTP Server 1.6 beta
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: пара вопросов в тему
От: Ed.ward Россия  
Дата: 18.06.03 07:06
Оценка:
Здравствуйте, Vadim B, Вы писали:

VB>Здравствуйте, Ed.ward, Вы писали:


EW>А по другому (но стандартными средствами) никак? А то у меня структура с единственным Int32 полем в сеарилизованном состоянии заняла 165! байт.


VB>Если тебе единственное поле надо переслать, или если надо переслать в виде потока байтов определенного формата (чтобы другая программа не на дотнете понимала, например), то посмотри в сторону System.BitConverter.GetBytes(). Обратное преобразование — System.BitConverter.ToInt32().


Мне надо пересылать кучу пакетиков туда-сюда.
Для простоты (как я это делал в С++) я структуру этих пакетиков описал структурами, а потом обнаружил, что сеарилизация создаст мне неплохой трафик, а другого способа представить структуру как массив байт я не нашел.

Пишу вот свой теперь преобразователь...

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Как это можно сделать в C#?
От: Ed.ward Россия  
Дата: 18.06.03 07:10
Оценка:
Здравствуйте, mihailik, Вы писали:

AVK>Для классов и структур все немножко посложнее

AVK>
AVK>//Твою структурку надо пометить как сериализуемую
AVK>...

AVK>//Ну а далее выбираешь сериализатор и вперед
AVK>


M>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.


Хм...
Я так понял, что мне под это дело нужно будет блок неупрявляемого кода писать?

К сожалению мне это не очень подходит...

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[5]: пара вопросов в тему
От: Vadim B  
Дата: 18.06.03 07:22
Оценка:
Здравствуйте, Ed.ward, Вы писали:

VB>>Если тебе единственное поле надо переслать, или если надо переслать в виде потока байтов определенного формата (чтобы другая программа не на дотнете понимала, например), то посмотри в сторону System.BitConverter.GetBytes(). Обратное преобразование — System.BitConverter.ToInt32().


EW>Мне надо пересылать кучу пакетиков туда-сюда.

EW>Для простоты (как я это делал в С++) я структуру этих пакетиков описал структурами, а потом обнаружил, что сеарилизация создаст мне неплохой трафик, а другого способа представить структуру как массив байт я не нашел.

EW>Пишу вот свой теперь преобразователь...


Аналогично. Мне нужно было передавать и принимать данные, подстраиваясь под существующий протокол, так что пришлось написать преобразователь, на нижнем уровне основанный на System.BitConverter, о котором я говорил выше.
Binary(Writer/Reader)
От: Ed.ward Россия  
Дата: 18.06.03 07:24
Оценка:
Здравствуйте, Vadim B, Вы писали:

VB>Здравствуйте, Ed.ward, Вы писали:


VB>>Если тебе единственное поле надо переслать, или если надо переслать в виде потока байтов определенного формата (чтобы другая программа не на дотнете понимала, например), то посмотри в сторону System.BitConverter.GetBytes(). Обратное преобразование — System.BitConverter.ToInt32().


EW>Мне надо пересылать кучу пакетиков туда-сюда.

EW>Для простоты (как я это делал в С++) я структуру этих пакетиков описал структурами, а потом обнаружил, что сеарилизация создаст мне неплохой трафик, а другого способа представить структуру как массив байт я не нашел.

EW>Пишу вот свой теперь преобразователь...


VB>Аналогично. Мне нужно было передавать и принимать данные, подстраиваясь под существующий протокол, так что пришлось написать преобразователь, на нижнем уровне основанный на System.BitConverter, о котором я говорил выше.


Угу
Только, по-моему, проще опираться сразу на Binary(Writer/Reader)

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[4]: Как это можно сделать в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.06.03 07:30
Оценка:
Здравствуйте, Ed.ward, Вы писали:

M>>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.


EW>Хм...

EW>Я так понял, что мне под это дело нужно будет блок неупрявляемого кода писать?

Нет, маршалер вполне managed. Просто ты можешь столкнуться с тем что после очередной версии у тебя старые данные перестанут работать.
... << RSDN@Home 1.1 alpha 1 >>
AVK Blog
Re[5]: Как это можно сделать в C#?
От: Ed.ward Россия  
Дата: 18.06.03 07:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Ed.ward, Вы писали:


M>>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.


EW>Хм...

EW>Я так понял, что мне под это дело нужно будет блок неупрявляемого кода писать?

AVK>Нет, маршалер вполне managed. Просто ты можешь столкнуться с тем что после очередной версии у тебя старые данные перестанут работать.


Marshals data from a managed object to an unmanaged block of memory.


[msdn]
public static void StructureToPtr(
object structure,
IntPtr ptr,
bool fDeleteOld
);

Parameters
structure
A managed object holding the data to be marshaled. This object must be an instance of a formatted class.
ptr
A pointer to an unmanaged block of memory, which must be allocated before this method is called.
fDeleteOld
true to have the Marshal.DestroyStructure method called on the ptr parameter before this method executes. Note that passing false can lead to a memory leak.
[/msdn]

Маршаллер то managed...

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.06.03 18:01
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.


Быстрее — да. Но проще . Это ты загнул. Ну, а вообще-то для быстрее было бы без Marshal. Просто взять и сериализовать это дело с помощью BinaryWriter-а по одному полю.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.06.03 18:01
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ну и что? unmanaged block of memory можно выделить из managed кода тем же маршаллером.


А зачем? Почему просто BinaryWriter-ром не записать все поля? Там полей-то...
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Binary(Writer/Reader)
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.06.03 18:01
Оценка:
Здравствуйте, Ed.ward, Вы писали:

EW>Только, по-моему, проще опираться сразу на Binary(Writer/Reader)


И проще и быстрее.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Binary(Writer/Reader)
От: Vadim B  
Дата: 19.06.03 05:57
Оценка:
Здравствуйте, Ed.ward, Вы писали:

VB>>Аналогично. Мне нужно было передавать и принимать данные, подстраиваясь под существующий протокол, так что пришлось написать преобразователь, на нижнем уровне основанный на System.BitConverter, о котором я говорил выше.


EW>Угу

EW>Только, по-моему, проще опираться сразу на Binary(Writer/Reader)

А как с помощью BinaryReader прочитать null-terminated string? А int32 с обратным порядком байтов (как при пересылке принято)? Если руками, то тогда не очень-то и проще получается.
Re[5]: Как это можно сделать в C#?
От: mihailik Украина  
Дата: 19.06.03 08:03
Оценка:
AVK>Нет, маршалер вполне managed. Просто ты можешь столкнуться с тем что после очередной версии у тебя старые данные перестанут работать.

Это если только формат своей структуры поменяется. Для таких случаев, конечно, нужно использовать Formatter.

А сам Marshal всегда будет работать одинаково — это же interop, его менять нельзя.
... << RSDN@Home 1.0 beta 7a >>
Re[4]: Как это можно сделать в C#?
От: Ed.ward Россия  
Дата: 19.06.03 08:09
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, mihailik, Вы писали:


M>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.


VD>Быстрее — да. Но проще . Это ты загнул. Ну, а вообще-то для быстрее было бы без Marshal. Просто взять и сериализовать это дело с помощью BinaryWriter-а по одному полю.


У меня примерно 50 структур содержащих от 1 до 10 полей.

Я вот написал через reflection теперь вот буду смотреть какой метод мне больше нравится

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[2]: Binary(Writer/Reader)
От: Ed.ward Россия  
Дата: 19.06.03 08:15
Оценка:
Здравствуйте, mihailik, Вы писали:

EW>Угу

EW>Только, по-моему, проще опираться сразу на Binary(Writer/Reader)

M>Тогда советую посмотреть на gotdotnet.com BinaryObjectWriter. Что-то среднее между сериализацией и Marshal.


M>Структуру можно разметить атрибутами, по ним этот BinaryObjectWriter её может читать и писать в поток байтов.


M>Метаданные, как и в способе с Marshal не пишутся, поэтому объём экономится. Но если структура поменяется — автоматически прочитать из старых данных не сможет.


M>Этот способ будет тормознее Marshal, но безопаснее.


Что-то я там такого не нашел

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[4]: Как это можно сделать в C#?
От: mihailik Украина  
Дата: 19.06.03 08:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, mihailik, Вы писали:


M>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.


VD>Быстрее — да. Но проще . Это ты загнул. Ну, а вообще-то для быстрее было бы без Marshal.


Да, проще было бы вообще через unsafe.


VD>Просто взять и сериализовать это дело с помощью BinaryWriter-а по одному полю.


Не сказал бы, что это просто. Кто гарантирует, что ты пишешь и читаешь все нужные поля и в том же порядке? Самому следить придётся, что неудобно. А если сюда Reflection прикрутить — совсем не просто получится по сравнению с Marshal.

Хотя для некоторых случаев это — лучший выход, конечно.
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Binary(Writer/Reader)
От: mihailik Украина  
Дата: 19.06.03 08:47
Оценка:
EW>Что-то я там такого не нашел

Может, BinaryObjectReader, а не ...Writer? Сейчас проверю...

Нашёл! Нужно писать раздельно: Binary Object Reader.

P.S. В примерах к нему есть чтение PE-файлов.
... << RSDN@Home 1.0 beta 7a >>
Re[5]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 10:20
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Да, проще было бы вообще через unsafe.


Тогда уж на С++. Забыть про нет и все дела.

VD>Просто взять и сериализовать это дело с помощью BinaryWriter-а по одному полю.


M>Не сказал бы, что это просто. Кто гарантирует, что ты пишешь и читаешь все нужные поля и в том же порядке?


У него в вопросе вроде блило то ли 1, то ли 2 поля (заранее известные).

M> Самому следить придётся, что неудобно. А если сюда Reflection прикрутить — совсем не просто получится по сравнению с Marshal.


Если следовать твоей логике, то стркутура может содержать ссылки...

M>Хотя для некоторых случаев это — лучший выход, конечно.


Вот его случай именно тако.

Ну, а если говорить о универсальном решении, то нужно пользоваться форматерами или переписывать всю сериализацию к чертям.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 10:20
Оценка:
Здравствуйте, Ed.ward, Вы писали:

EW>Я вот написал через reflection теперь вот буду смотреть какой метод мне больше нравится


Учти что рефлекшон — это довольно медленно. Я бы посоветовал сделать так. Создать небольшую утилитку которая используя рефлекшон и список типов генерировала бы код (на C#) сериализации с использованием BinaryWriter-а, компилировала бы этот код и создавала сборку содержащую сериализатор для нужных типов.

Хотя если передача ведется через сетку, то скорее всего затраты на передачу по сети будут не соизмеримы с затратами на чтение решлекшона.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 10:20
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Это если какую нибудь конкретную структуру.


Речь вроде и шла о конкретных.

AVK>А если любую? Через рефлекшен?


А почему бы и нет. Если главное компактность, а на времы можно наплевать, то очень даже выход. Ну, а если нужно и быстро и компактно, то нужно генерировать код сериализации во время компиляции.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Binary(Writer/Reader)
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 10:20
Оценка:
Здравствуйте, Vadim B, Вы писали:

VB>А как с помощью BinaryReader прочитать null-terminated string? А int32 с обратным порядком байтов (как при пересылке принято)? Если руками, то тогда не очень-то и проще получается.


Если с обоих сторн дотнет, то нефига париться. BinaryReader будет читать и писать днные одинаково. В дотнете попросту нет "null-terminated string". В нем есть просто строка. И BinaryReader/BinaryWriter прекрасно умеет их писать. Вот только они юникодные.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 10:20
Оценка:
Здравствуйте, Vyacheslav_M, Вы писали:

V_M>дак вот, надо эту переменную, структуру и массив байтов запихать в другой массив байтов

V_M>что бы отправить в socket а на клиентской стороне все это вытащить из того же массива байтов.
V_M>Как все это организовать без указателей?

Кстати, если у тебя с обох сторон дотнет. То проще не париться с структурами, а использовать вместо них DataTable. Винарную сериализацию для DataTable я уже давно написал http://www.rsdn.ru/forum/Message.aspx?mid=247335&amp;only=1
Автор: VladD2
Дата: 21.04.03
.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Как это можно сделать в C#?
От: mihailik Украина  
Дата: 19.06.03 15:28
Оценка:
M>Да, проще было бы вообще через unsafe.

VD>Тогда уж на С++. Забыть про нет и все дела.


Ну да, тоже нормально.


M>Хотя для некоторых случаев это — лучший выход, конечно.


VD>Вот его случай именно тако.


VD>Ну, а если говорить о универсальном решении, то нужно пользоваться форматерами или переписывать всю сериализацию к чертям.


Binary Object Reader поможет.
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Binary(Writer/Reader)
От: Vadim B  
Дата: 19.06.03 15:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VB>>А как с помощью BinaryReader прочитать null-terminated string? А int32 с обратным порядком байтов (как при пересылке принято)? Если руками, то тогда не очень-то и проще получается.


VD>Если с обоих сторн дотнет, то нефига париться. BinaryReader будет читать и писать днные одинаково. В дотнете попросту нет "null-terminated string". В нем есть просто строка. И BinaryReader/BinaryWriter прекрасно умеет их писать. Вот только они юникодные.


Если с обеих сторон дотнет — то да. Я имел в виду свою ситуацию, когда есть некоторый сетевой протокол, в котором фигурируют и null-terminated strings, и int с сетевым (обратным интелловскому) порядком байт, а с другой стороны может быть что угодно — дотнет, MFC, Java, или фиговинка на микроконтроллере.
Re[4]: Binary(Writer/Reader)
От: mihailik Украина  
Дата: 19.06.03 15:40
Оценка:
VB>Если с обеих сторон дотнет — то да. Я имел в виду свою ситуацию, когда есть некоторый сетевой протокол, в котором фигурируют и null-terminated strings, и int с сетевым (обратным интелловскому) порядком байт, а с другой стороны может быть что угодно — дотнет, MFC, Java, или фиговинка на микроконтроллере.

Ну так посмотри, как BinaryReader/Writer устроен. И переделай.
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Как это можно сделать в C#?
От: Nick Notabene Россия  
Дата: 19.06.03 16:58
Оценка:
Сорри за глупый вопрос..
... Skipped
AVK>>Для классов и структур все немножко посложнее
AVK>>
AVK>>//Твою структурку надо пометить как сериализуемую
AVK>>...

AVK>>//Ну а далее выбираешь сериализатор и вперед
AVK>>


M>Можно быстрее и дешевле, используя System.Runtime.InteropServices.Marshal и его методы StructureToPtr и Copy.

... Skipped

Люди, простите меня глупого. Неужели это правда быстрее и дешевле, чем одна структура и функия send ???
2Ed.ward — а чем был плох первоначальный вариант ?
private struct s
{
public bool Move;
public int xPos;
public int yPos;
}
s tmp;

и массив байтов
byte[]=new byte[n];

send(...)
Интуитивно понятный интерфейс — это интерфейс, для работы с которым нужна недюжинная интуиция...
Re[4]: Как это можно сделать в C#?
От: Ed.ward Россия  
Дата: 19.06.03 17:03
Оценка:
Здравствуйте, Nick Notabene, Вы писали:

NN>Люди, простите меня глупого. Неужели это правда быстрее и дешевле, чем одна структура и функия send ???

NN>2Ed.ward — а чем был плох первоначальный вариант ?
NN>private struct s
NN>{
NN>public bool Move;
NN>public int xPos;
NN>public int yPos;
NN>}
NN>s tmp;

NN>и массив байтов

NN>byte[]=new byte[n];

NN>send(...)


Не совсем понял, первоначальный вариант это с сеарилизацией с помощью BinaryFormatter?

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re[4]: Как это можно сделать в C#?
От: mihailik Украина  
Дата: 19.06.03 17:06
Оценка:
NN>Люди, простите меня глупого. Неужели это правда быстрее и дешевле, чем одна структура и функия send ???

Кто такой, почему не знаю?
... << RSDN@Home 1.0 beta 7a >>
Re[7]: Как это можно сделать в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.03 21:23
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Binary Object Reader поможет.


Как я понял он не универсален. Для него нужна особая раметка. И еще не ясно что у него со скоростью. Скорее всего он не намного быстрее чем форматеры.
... << RSDN@Home 1.1 alpha 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Как это можно сделать в C#?
От: mihailik Украина  
Дата: 20.06.03 15:47
Оценка:
M>Binary Object Reader поможет.

VD>Как я понял он не универсален. Для него нужна особая раметка. И еще не ясно что у него со скоростью. Скорее всего он не намного быстрее чем форматеры.


Насчёт разметки — примерно как с Marshal, нужна когда что-то особенное.

Скорость — ясное дело — плохая, там же Reflection.
... << RSDN@Home 1.0 beta 7a >>
Re[5]: Как это можно сделать в C#?
От: Nick Notabene Россия  
Дата: 20.06.03 16:25
Оценка:
Здравствуйте, Ed.ward, Вы писали:
EW>Не совсем понял, первоначальный вариант это с сеарилизацией с помощью BinaryFormatter?

Гы. Читаю я эту нитку и кажется мне что лечение много хуже болезни...
Ed.ward, у тебя и отправитель и получатель знают формат структуры и буфера ?
Зачем тогда весь этот многопудовый геморрой ???


M>Кто такой, почему не знаю?


Есть такая фунция send, в ws2_32.dll Если уж необходимо делать все на С#, то [DllImport] ваше спасение...

Прав был Оккам, сто раз прав, и неудержимый рост глючных приложенийпод .Net наглядное тому подтверждение...

Гы.


EW>Ed.ward
Интуитивно понятный интерфейс — это интерфейс, для работы с которым нужна недюжинная интуиция...
Re[6]: Как это можно сделать в C#?
От: Ed.ward Россия  
Дата: 21.06.03 10:59
Оценка:
Здравствуйте, Nick Notabene, Вы писали:

NN>Здравствуйте, Ed.ward, Вы писали:

EW>Не совсем понял, первоначальный вариант это с сеарилизацией с помощью BinaryFormatter?

NN>Гы. Читаю я эту нитку и кажется мне что лечение много хуже болезни...

NN>Ed.ward, у тебя и отправитель и получатель знают формат структуры и буфера ?
NN>Зачем тогда весь этот многопудовый геморрой ???


M>Кто такой, почему не знаю?


NN>Есть такая фунция send, в ws2_32.dll Если уж необходимо делать все на С#, то [DllImport] ваше спасение...


NN>Прав был Оккам, сто раз прав, и неудержимый рост глючных приложенийпод .Net наглядное тому подтверждение...


NN>Гы.




Если бы я хотел пользоваться функцией send из ws2_32.dll напрямую, я писал бы программу на С++ с которым работаю вот уже 6 лет.
Мне интересно написать программу под .NET чистенькую чтоб всем спецификациям соответствовала...
Именно интересно а не нужно.

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.