Переинтерпретировать вектор с плавающей точкой как массив без знака и обратно - PullRequest
3 голосов
/ 23 декабря 2009

Я искал и искал stackoverflow для ответа, но не нашел то, что мне было нужно.

У меня есть процедура, которая принимает массив без знака в качестве параметра, чтобы закодировать его как Base64. Я хотел бы закодировать вектор с плавающей запятой STL (вектор) в Base64, и, следовательно, потребуется переосмыслить байты вектора с плавающей запятой как массив символов без знака, чтобы передать его в процедуру кодирования. Я пробовал несколько вещей, от переинтерпретации и статических приведений, до мем-копий и т. Д., Но ни одна из них, похоже, не работает (по крайней мере, не так, как я их реализовал).

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

Вот урезанная версия моего кода C ++ для кодирования:

std::string
EncodeBase64FloatVector( const vector<float>& p_vector )
{
  unsigned char* sourceArray;

  // SOMEHOW FILL THE sourceArray WITH THE FLOAT VECTOR DATA BITS!!

  char* target;
  size_t targetSize = p_vector.size() * sizeof(float);
  target = new char[ targetSize ];

  int result = EncodeBase64( sourceArray, floatArraySizeInUChars, target, targetSize );

  string returnResult;
  if( result != -1 )
  {
    returnResult = target;
  }
  delete target;
  delete sourceArray;
  return returnResult;
}

Любая помощь будет принята с благодарностью. Благодаря.

Raymond.

Ответы [ 3 ]

7 голосов
/ 23 декабря 2009

std::vector гарантирует, что данные будут смежными, и вы можете получить указатель на первый элемент в векторе, взяв адрес первого элемента (при условии, что он не пустой).

typedef unsigned char byte;
std::vector<float> original_data;
...
if (!original_data.empty()) {
  const float *p_floats = &(original_data[0]);  // parens for clarity

Теперь, чтобы рассматривать это как массив unsigned char, вы используете reinterpret_cast:

  const byte *p_bytes = reinterpret_cast<const byte *>(p_floats);
  // pass p_bytes to your base-64 encoder
}

Возможно, вы захотите закодировать длину вектора перед остальными данными, чтобы упростить их декодирование.

ВНИМАНИЕ: Вам по-прежнему нужно беспокоиться о порядке байтов и представления. Это будет работать только в том случае, если вы читаете обратно на той же платформе (или совместимой), с которой написали.

5 голосов
/ 23 декабря 2009
sourceArray = reinterpret_cast<const unsigned char *>(&(p_vector[0]))
0 голосов
/ 23 декабря 2009

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

Если вы используете это, вам придется делать свою собственную кодировку base64 в то же время, поскольку protobuf кодирует данные, предполагая, что у вас есть 8-битный чистый канал для работы. Но это довольно тривиально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...