Считывание объявлений

Здесь обсуждаются технические аспекты создания дополнений.
ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Считывание объявлений

Сообщение ОреЛ » 23:22, 20.03.2011

Плагин, читающий объявление с заданным в коде ID и отображающий варианты ответов опроса:
http://www.commfort.com/tmp/plugin_read_board_post.rar
написан в BCB 2009

кому нужно, могу выложить полное считывание всех разделов, но только в MVS C++ 2010

Код: Выделить всё

void ReadParts(){
   BYTE* buf;
   DWORD size;
   string BotName = TextToString(BOTNAME);//здесь преобразуется имя виртуального пользователя из wstring в string
   size = CommFortGetData(dwPluginID, 1070, NULL, NULL, (BYTE*)BotName.c_str(), BotName.length());
   buf = new BYTE[size];
   CommFortGetData(dwPluginID, 1070, buf, size, (BYTE*)BotName.c_str(), BotName.length());
   int count;
   memcpy(&count, buf, 4);
   buf += 4;
   for (int i = 0; i < count; i++){
                int ID;
      memcpy(&ID, buf, 4);
      buf += 4;
      memcpy(&size, buf, 4);
      buf += 4;
                wstring Name;
      Name.resize(size);
      memcpy((void*)Name.c_str(), buf, size * 2);
      buf += size * 2;         
      memcpy(&size, buf, 4);
      buf += 4;
                wstring Description;
      Description.resize(size);
      memcpy((void*)Description.c_str(), buf, size * 2);
      buf += size * 2;
      ReadAdvertsFromPart(ID);//считать все объявления выбранно раздела ДО
   }
   delete[] buf;
}

void ReadAdvertsFromPart(int PartID){
   BYTE* buf;
   DWORD size;
   string Data = IntegerToString(PartID);
   size = CommFortGetData(dwPluginID, 1071, NULL, NULL, (BYTE*)Data.c_str(), Data.length());
   buf = new BYTE[size];
   CommFortGetData(dwPluginID, 1071, buf, size, (BYTE*)Data.c_str(), Data.length());
   int count;
   memcpy(&count, buf, 4);//число(количество)
   buf += 4;      
   for (int i = 0; i < count; i++){
      int ID;
      memcpy(&ID, buf, 4);//(число(ID объявления)
      buf += 4;
      double DateTime;
      memcpy(&DateTime, buf, 8);//дата_и_время(публикации объявления)
      buf += 8;
      memcpy(&size, buf, 4);
      buf += 4;   
      wstring AuthorName;      
      AuthorName.resize(size);
      memcpy((void*)AuthorName.c_str(), buf, size * 2);//текст(имя автора)
      buf += size * 2;         
      memcpy(&size, buf, 4);
      buf += 4;
      wstring Title;
      Title.resize(size);
      memcpy((void*)Title.c_str(), buf, size * 2);//текст(заголовок объявления)
      buf += size * 2;
      int CountComments;
      memcpy(&CountComments, buf, 4);//число(количество комментариев)
      buf += 4;
      ReadSingleAdvert(ID);
   }   
}

void ReadSingleAdvert(int ID){
   BYTE* buf;
   DWORD size;
   string Data = IntegerToString(ID); //ID объявления
   size = CommFortGetData(dwPluginID, 1072, NULL , NULL, (BYTE*)Data.c_str(), aInBuffer.length());
   buf = new BYTE[size];
   CommFortGetData(dwPluginID, 1072, buf, size, (BYTE*)Data.c_str(), aInBuffer.length());
   double DateTime;
   memcpy(&DateTime, buf, 8);
   buf += 8;
   double Expired;
   memcpy(&Expired, buf, 8);
   buf += 8;
   memcpy(&size, buf, 4);
   buf += 4;
   wstring AuthorName;
   AuthorName.resize(size);
   memcpy((void*)AuthorName.c_str(), buf, size * 2);
   buf += size * 2;
   memcpy(&size, buf, 4);
   buf += 4;
   wstring Header;
   Header.resize(size);
   memcpy((void*)Header.c_str(), buf, size * 2);
   buf += size * 2;
   memcpy(&size, buf, 4);
   buf += 4;
   wstring Text;
   Text.resize(size);
   memcpy((void*)Text.c_str(), buf, size * 2);
   buf += size * 2;
   memcpy(&size, buf, 4);
   buf += 4;
   wstring Question;
   Question.resize(size);
   memcpy((void*)Question.c_str(), buf, size * 2);
   buf += size * 2;
   int iAnswersCount;
   memcpy(&iAnswersCount, buf, 4);
   if (iAnswersCount > 0){
           buf += 4;
      for(int j = 0; j < iAnswersCount; j++){
         wstring AnswerText;
         memcpy(&size, buf, 4);
         buf += 4;
         AnswerText.resize(size);
         memcpy((void*)AnswerText.c_str(), buf, size * 2);
         buf += size * 2;
         int VotesCount;// = fReadInteger(buf, &i);
         memcpy(&VotesCount, buf, 4);
         buf += 4;
      }   
   }
   int CommentsCount;
   memcpy(&CommentsCount, buf, 4);
   if (CommentsCount > 0){
      buf += 4;
      for (int j = 0; j < CommentsCount; j++){
         int CommentID;
         memcpy(&CommentID, buf, 4);
         buf += 4;
         double CommentDateTime;
         memcpy(&CommentDateTime, buf, 8);
         buf += 8;         
         wstring CommentAuthor;
         memcpy(&size, buf, 4);
         buf += 4;
         CommentAuthor.resize(size);
         memcpy((void*)CommentAuthor.c_str(), buf, size * 2);
         buf += size * 2;
         memcpy(&size, buf, 4);
         buf += 4;
         wstring CommentText;
         Comment.resize(size);
         memcpy((void*)Comment.c_str(), buf, size * 2);
         buf += size * 2;
      }
   }
   delete[] buf;   
}

string TextToString(wstring Text){
   int Length = Text.length();
   string Return;
   Return.resize(4 + Length * 2);
   memcpy((void*)Return.c_str(), &Length, 4);
   memcpy((void*)(Return.c_str() + 4), Text.c_str(), Length * 2);
   return Return;
}

string IntegerToString(int Value){
   string Return;
   Return.resize(4);
   memcpy((void*)Return.c_str(), &Value, 4);
   return Return;
}
Последний раз редактировалось ОреЛ 13:10, 16.04.2011, всего редактировалось 5 раз.
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Считывание обявления

Сообщение Maxim Mirgorodsky » 12:50, 21.03.2011

Сначала необходимо получить список разделов доски объявлений (получение данных от программы, ID=1070), затем список объявлений в разделе (ID=1071) и только после этого можно получить само объявление и комментарии к нему (ID=1072).

Подскажите, на каком этапе проблемы? Или просто необходим пример в котором все эти действия производятся?

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание обявления

Сообщение ОреЛ » 14:17, 21.03.2011

Мне скорее нужен рабочий пример считывания объявлений. У меня вываливается ошибка APPCRASH с пометкой на StackHash. Просто у меня не получается считать само объявление со всеми там опросами и комментариями.
Так то все разделы я естественно успешно считываю. у меня все последовательно Раздел->Объявления->Объявление
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Считывание обявления

Сообщение Maxim Mirgorodsky » 18:18, 22.03.2011

На каком этапе ошибка? 1070, 1071 или 1072?

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание обявления

Сообщение ОреЛ » 19:10, 22.03.2011

Говорю в третий раз :) У меня проблема со считывание единичного объявления, его опроса и комментариев. Говорю, чтобы было понятно вам: 1072.
Мне просто нужен код. Мне просто нужно сравнить и понять, что я делаю не так.
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Считывание обявления

Сообщение Maxim Mirgorodsky » 19:13, 22.03.2011

Завтра проверим.

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание обявления

Сообщение ОреЛ » 19:32, 22.03.2011

Ааа, печаль ;( Мне нужен был рабочий код уже в пятницу ;(
Ладно, буду мучаться и ждать и надеяться.
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Считывание обявления

Сообщение Maxim Mirgorodsky » 10:29, 23.03.2011

Плагин, читающий объявление с заданным в коде ID и отображающий варианты ответов опроса:
http://www.commfort.com/tmp/plugin_read_board_post.rar

Внимательно просмотрите вспомогательные функции у себя, нет ли в них ошибки (fReadText, fReadInteger и т.п.).

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание обявления

Сообщение ОреЛ » 12:13, 23.03.2011

Максим, спасибо Вам большое за уделенное внимание. Спасибо за вкусняшки, закомментированные в main.cpp. Я боюсь раскрывать правду своей ошибки, ибо ошибка будет банальна и глупа до безумия.
И еще, я не использую вспомогательных функций типа fReadText, fReadInteger, лишь только перевожу в строку значения для отправки при помощи вспомогательной функции, и то этого можно не делать, используя указатель на массив BYTE и немного терпения :)
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Считывание обявления

Сообщение Maxim Mirgorodsky » 12:33, 23.03.2011

Спасибо за вкусняшки, закомментированные в main.cpp


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

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание объявления

Сообщение ОреЛ » 19:27, 23.03.2011

Объявление считывает нормально теперь, после того, как я нашел ошибку, но вот с комментариями что-то не то.
При добавлении кода:

Код: Выделить всё

   for(int i=0;i<iCommentsCount;i++){
      int iCommentId = fReadInteger(buf,&iOffset);
      double dCommentDateTime = fReadDouble(buf,&iOffset);
      wstring uCommentAuthor = fReadText(buf, &iOffset);
      wstring uCommentText = fReadText(buf,&iOffset);
   }

начинают твориться странные чудеса, а именно:
E26 [23.03.2011 18:27:01.275] ошибка приложения: "External exception E06D7363"
И сервер начинает занимать вместо 10 мб памяти при запуске целых 855. Что я делаю не так?
UPD: количество комментариев передает правильно, ID комментария и дату тоже, дальше какие-то косяки
UPD2: сервер передает неправильный размер имени автора комментария (uCommentAuthor), там неимоверно большие цифры, в следствии чего и происходит выделение такого огромного количества памяти =\
Максим, если что, вы знаете, где меня искать
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Аватара пользователя
supermet
Сообщения: 244
Зарегистрирован: 02:35, 19.07.2009

Re: Считывание объявления

Сообщение supermet » 22:11, 23.03.2011

А переменная buf - какого типа? Это я так понял массив char[]. Может переполнение этого массива?

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание объявления

Сообщение ОреЛ » 22:33, 23.03.2011

Ну нет же.
Я работаю с указателями на массив типа BYTE.
Говорю же, передает неверный размер переменной, отвечающий за имя автора.
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание объявления

Сообщение ОреЛ » 14:04, 24.03.2011

Проблема решена. Ссылку перенесу в первый пост, если что.
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

Re: Считывание объявлений

Сообщение ОреЛ » 16:30, 26.05.2011

Максим, скажите пожалуйста, считывание объявлений возможно без подключения виртуального пользователя? И получение событий Добавления/Редактирования/Удаления объявления/комментария тоже возможно без подключения виртуального пользователя?
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding

Ответить