У меня есть приложение C#, которое считывает/записывает сообщения с определенного предопределенного протокола с/на USB. Поэтому у меня есть как минимум 2 варианта. Один - сериализовать/десериализовать. Другой - маршал. Сначала я выбирал первый вариант, и он работал нормально. Но после того, как все больше и больше типов сообщений введены, меня раздражает громоздкая реализация для каждого типа сообщения и чувствую, что маршал может быть лучшим способом. Раньше я не использовал маршала. Правильно ли это? Я сделал несколько тестов. Одна из проблем, с которой я сталкиваюсь, - это когда у меня есть структура с массивом, как писать на нее? Такие, как: -C# Marshalling vs Serialization
[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct SomeData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public sbyte[] data;
/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}
Оказывается, что данные и пробы являются ссылками, и я должен новым объект, чтобы использовать их, что звучит не совсем правильно меня. Мне нужно, чтобы вся структура была непрерывным блоком памяти, и я не думаю, что новый оператор сделает это для меня.
Любое предложение действительно оценили
Ниже показано, как я сделал с помощью сериализации.
List<byte> rawData = new List<byte>();
rawData.AddRange(BitConverter.GetBytes(ProtocolVersion));
// 16 bytes for operator ID
byte[] temp = new byte[16];
Array.Copy(Encoding.ASCII.GetBytes(OperatorId), temp, OperatorId.Length > temp.Length ? temp.Length : OperatorId.Length);
rawData.AddRange(temp);
// 16 bytes for operator password
Array.Clear(temp, 0, temp.Length);
Array.Copy(Encoding.ASCII.GetBytes(OperatorPassword), temp, OperatorPassword.Length > temp.Length ? temp.Length : OperatorPassword.Length);
rawData.AddRange(temp);
Ниже, как я сделал на сортировочной
static byte[] RawSerialize<T>(T obj)
{
if (obj == null)
{
return null;
}
int size = Marshal.SizeOf(obj);
byte[] result = new byte[size];
IntPtr buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(obj, buffer, false);
Marshal.Copy(buffer, result, 0, size);
return result;
}
Существуют способы сериализации и десериализации в общем виде с очень маленькой церемонией. Можете ли вы показать нам, как вы это делаете? –
Кроме того, если вы могли бы рассказать нам немного больше о том, почему сериализация не работает для вас, и почему вы думаете, что маршалинг может быть лучше, это было бы здорово. –
У меня есть пример кода. Я не сказал, что это не работает. Просто потому, что мне приходится разбирать сообщения для разных типов. – leon