отправка varint без удаления CodedOutputStream, ZeroCopyOutputStream

#c #protocol-buffers

#c #протокол-буферы

Вопрос:

Мое приложение отправляет varint много раз. Каждый раз, когда мне приходится выделять память для 2 объектов: CodedOutputStream и FileOutputStream, а затем повторно использовать его. ИМО, это ненужная потеря времени. Как я могу отправить varint без всего этого процесса? (Я не хочу делать это вручную, но с помощью protobuf)


Я нашел это:

 delete coded_output;
  /*  delete raw_output;*/
  ((FileOutputStream*)raw_output)->Flush();
  

но все равно есть один объект, который нужно выделять каждый раз


   void Connection::send(const Messageamp; msg) throw(EmptyMessage) {
    //CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
    CodedOutputStream coded_output(raw_output);
    int n = msg.ByteSize();
    if(n<=0) throw EmptyMessage();
    //coded_output->WriteVarint32(n);
    coded_output.WriteVarint32(n);
    //delete coded_output;
    coded_output.~CodedOutputStream();
    raw_output->Flush();
    msg.SerializeToArray(buffer, n);
    SocketMaintenance::write(buffer, n);
  }

  Annoucement Connection::receive() throw(EmptySocket) {
    //CodedInputStream* coded_input = new CodedInputStream(raw_input);
    CodedInputStream coded_input(raw_input);
    google::protobuf::uint32 n;
    //coded_input->ReadVarint32(amp;n);
    coded_input.ReadVarint32(amp;n);
    char *b;
    int m;
    //coded_input->GetDirectBufferPointer((const void**)amp;b, amp;m);
    coded_input.GetDirectBufferPointer((const void**)amp;b, amp;m);
    Annoucement ann;
    ann.ParseFromArray(b, n);
    return ann;
  }
  

Когда я использую приведенный выше код, я получаю эту ошибку (ошибка времени выполнения) из моего клиентского приложения (это приложение использует только функцию отправки):

libprotobuf ФАТАЛЬНЫЙ google/protobuf/io/zero_copy_stream_impl_lite.cc:346] ОШИБКА ПРОВЕРКИ: (buffer_used_) == (buffer_size_): BackUp() может быть вызван только после Next(). terminate вызывается после создания экземпляра ‘google::protobuf::FatalException’
что(): ОШИБКА ПРОВЕРКИ: (buffer_used_) == ( buffer_size_): функция BackUp() может быть вызвана только после функции Next(). Остановлено

Когда я использую закомментированную часть кода вместо соответствующей, все работает нормально.

Комментарии:

1. Вы уничтожаете coded_output дважды — один раз явно, затем снова неявно в конце функции. Я предлагаю вам позволить ему быть уничтоженным в нужное время обычным способом — вставить открытую фигурную скобку непосредственно перед его объявлением и заменить явный вызов деструктора закрывающей фигурной скобкой.

Ответ №1:

Вам не обязательно размещать CodedOutputStream в куче, вы можете просто объявить его как локальную переменную (или член класса) там, где вам это нужно. Не похоже, что конструктор особенно дорогой.

Вы всегда записываете в один и тот же файл? Если это так, вы можете просто использовать один CodedOuputStream и FileOutputStream для всех операций записи.

Комментарии:

1. Я только что попробовал. Я должен удалить его, прежде чем пользователь удалит файл из FileOutputStream. Если я этого не сделаю, я получаю: libprotobuf ФАТАЛЬНЫЙ google / protobuf / io/zero_copy_stream_impl_lite.cc:346] ОШИБКА ПРОВЕРКИ: (buffer_used ) == (buffer_size_): BackUp() может быть вызван только после Next(). terminate вызывается после создания экземпляра ‘google:: protobuf::FatalException’ что(): ОШИБКА ПРОВЕРКИ: ( buffer_used_) == (buffer_size_): функция BackUp() может быть вызвана только после функции Next(). Остановлено_

2. Я попробовал coded_output. ~ CodedOutputStream() вместо удаления coded_output, но безуспешно.

3. Я решил добавить, как это выглядит в вопросе.