2015-10-14 1 views
0

Я пишу протокол межпроцессного взаимодействия, где aC# клиент вызывает API в серверном процессе, который будет написан на разных языках (Java, C, C++ и т. Д.) Оба процесса работать на том же компьютере, и сам коммуникационный уровень не является проблемой (в настоящее время я использую сокеты, поскольку он поддерживается большинством языков, но может использовать разделяемую память позже) Всего около 180 API, каждый из которых, конечно, имеет свои собственные набор параметров различных типов. Поскольку сервер может быть написан на любом языке, я преобразую все параметры в массив байтов, поместил его в пакет с идентификатором API и передал его другому процессу, где он будет декодирован на основе идентификатора API. Возвращенные данные из процесса сервера будут отформатированы одинаково.Создание пакета обмена между процессами

Что я ищу - это самый быстрый способ (и предпочтительно одна функция), который принимает переменное число параметров другого типа и преобразует их в массив байтов. В настоящее время я использую класс BitConverter, чтобы преобразовать каждый параметр в массив байтов и объединить все массивы в один. Нет ссылочных параметров, кроме строк, которые будут преобразованы в массив байтов с первой длиной строки, содержащей 2 байта. У меня есть контроль над клиентом и сервером, поэтому каждый знает, какой порядок параметров ожидать в пакете (на основе идентификатора API) и размер каждого параметра.

Если есть другой способ сделать это, или как сделать это с помощью одной функции, как:

byte[] toByteArray (variable-number of different-type parameters…) 

Пожалуйста, дайте мне знать. Производительность является проблемой, поскольку частота вызовов API довольно высока.

ответ

0

Я думаю, вы должны попробовать протокол Буферы Google: https://developers.google.com/protocol-buffers/

Protobuf зависит от языка. Таким образом, вы определяете свои собственные структуры, а затем генерируете конкретный код для Java, C#, C++ и т. Д.

0

Я решил использовать следующий код. Первоначально был обеспокоен ударом с использованием параметров и бокса/распаковки, но после некоторого профилирования он оказался незначительным. Здесь это для всех, кого это интересует.

public static int ToByteArray (byte[] bytes, int Offs, params object[] args) 
    { 
     int CurrIdx = Offs; 

     for (int i=0; i<args.Length; i++) 
     { 
      object obj = args[i]; 
      if (obj is int) 
      { 
       int x = (int) obj; 
       bytes[CurrIdx++] = (byte)(x & 0xff); 
       bytes[CurrIdx++] = (byte)((x >> 8) & 0xff); 
       bytes[CurrIdx++] = (byte)((x >> 16) & 0xff); 
       bytes[CurrIdx++] = (byte)((x >> 24) & 0xff); 
      } 
      else if (obj is double) 
      { 
       double x = (double)obj; 
       System.Buffer.BlockCopy(BitConverter.GetBytes(x), 0, bytes, CurrIdx, sizeof(double)); 
       CurrIdx += sizeof(double); 
      } 
      else if (obj is string) 
      { 
       string x = (string)obj; 
       int ByteLen = x.Length * sizeof(char); 
       bytes[CurrIdx++] = (byte)(x.Length & 0xff); 
       bytes[CurrIdx++] = (byte)((x.Length >> 8) & 0xff); 
       System.Buffer.BlockCopy(x.ToCharArray(), 0, bytes, CurrIdx, ByteLen); 
       CurrIdx += ByteLen; 
      } 
     } 
     return (CurrIdx - Offs); 
    }