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

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

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

Сообщение ОреЛ »

Плагин, читающий объявление с заданным в коде 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
Администратор
Сообщения: 6867
Зарегистрирован: 09:56, 27.06.2005

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

Сообщение Maxim Mirgorodsky »

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

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

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

Сообщение ОреЛ »

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

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

Сообщение Maxim Mirgorodsky »

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

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

Сообщение ОреЛ »

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

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

Сообщение Maxim Mirgorodsky »

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

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

Сообщение ОреЛ »

Ааа, печаль ;( Мне нужен был рабочий код уже в пятницу ;(
Ладно, буду мучаться и ждать и надеяться.
Когда пишете программу, всегда думайте о том, что её может затем поддерживать психопат и насильник, который знает где вы живёте.
— Martin Golding
Maxim Mirgorodsky
Администратор
Сообщения: 6867
Зарегистрирован: 09:56, 27.06.2005

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

Сообщение Maxim Mirgorodsky »

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

Внимательно просмотрите вспомогательные функции у себя, нет ли в них ошибки (fReadText, fReadInteger и т.п.).
ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

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

Сообщение ОреЛ »

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

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

Сообщение Maxim Mirgorodsky »

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

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

Сообщение ОреЛ »

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

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

	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
Сообщения: 245
Зарегистрирован: 02:35, 19.07.2009

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

Сообщение supermet »

А переменная buf - какого типа? Это я так понял массив char[]. Может переполнение этого массива?
ОреЛ
Сообщения: 376
Зарегистрирован: 11:18, 11.07.2008
Откуда: Ульяновск
Контактная информация:

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

Сообщение ОреЛ »

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

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

Сообщение ОреЛ »

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

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

Сообщение ОреЛ »

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