Страница 11 из 28

Re: Вопросы и ответы по программированию.

Добавлено: 20.10.2011, 17:18
nikit-xxx
нужна помощь по примеру 5.11 из K&R
Скрытое содержимое

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

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000	//max число строк
char *lineptr[MAXLINES]; //Указатели на строки

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(void *, void *));
int numcp(char *, char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines;//кол-во считанных строк
	int numeric = 0; //1 если числовая сортировка

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(void *, void *))(numeric ? numcp : strcmp));//указатель на функцию вида int function(void *, void *); к function присвоится numcp либо strcmp
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sortn");
		return 1;
	}
}
/////////////////////////
/////////////////////////
/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	//ничего не делать, если в массиве
		return;			//меньше двух элементов
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(char *s1, char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%sn", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='n'; ++i)
		s[i] = c;
	if (c == 'n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 //объём имеющейся памяти

static char allocbuf[ALLOCSIZE]; //буфер памяти для alloc
static char *allocp = allocbuf; //Следующая свободная позиция

char *alloc(int n) //возвращает указатель на n символов
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { //есть место
		allocp += n;
		return allocp - n; //старый p
	} else //недостаточно места в буфере
		return 0;
}
первую проблему "уже определена ф-я qsort();" я решил переименованием в qsort_(),
сейчас компилятор выдаёт

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

Examples 35.11.c||In function 'main':|
Examples 35.11.c|23|warning: pointer type mismatch in conditional expression|
||=== Сборка закончена: 0 ошибок, 1 предупреждений ===|
я не понимаю, где/почему в 23-ей строке компилятор находит несоответствие типов, и не совсем понимаю как в этой строке работает в 4-ом аргументе qsort_ конструкция

qsort_((void **) lineptr, 0, nlines-1, (int (*)(void *, void *))(numeric ? numcp : strcmp));

в частности скобки ()(), выделенные розовым, где можно посмотреть подробнее про этот приём?

Насколько я понял, в 4-й аргумент qsort_ пойдёт в зависимости от истинности numeric указатель на numcp или strcmp, но тогда зачем прописывать тип возвращаемого значения и аргументы функции, на которую указывает этот указатель ?

Объясните плз чтобы нубу понятно было.

P. S. компилятор gcc-4.4.1., среда Code::Blocks 10.5

Добавлено спустя 2 часа 20 минут 20 секунд:
путь ложный, не смотреть

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

qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(void *, void *))(numeric ? numcp : strcmp));
Заменил на это (так вообще можно делать???)

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

if(numeric){
	qsort_((void **) lineptr, 0, nlines-1, *numcp);
}else{
	qsort_((void **) lineptr, 0, nlines-1, *strcmp);
}
но компилятор всёравно ругается

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

\Examples 3\5.11 new fix by me.c||In function 'main':|
\Examples 3\5.11 new fix by me.c|25|warning: passing argument 4 of 'qsort_' from incompatible pointer type|
\Examples 3\5.11 new fix by me.c|9|note: expected 'int (*)(void *, void *)' but argument is of type 'int (*)(char *, char *)'|
\Examples 3\5.11 new fix by me.c|27|warning: passing argument 4 of 'qsort_' from incompatible pointer type|
\Examples 3\5.11 new fix by me.c|9|note: expected 'int (*)(void *, void *)' but argument is of type 'int (*)(const char *, const char *)'|
||=== Сборка закончена: 0 ошибок, 2 предупреждений ===|
то есть по какой-то причине разрабы GCC запретили обобщение указателя при помощи void*

Re: Вопросы и ответы по программированию.

Добавлено: 20.10.2011, 18:23
Pr0Ger
nikit-xxx писал(а):но тогда зачем прописывать тип возвращаемого значения и аргументы функции, на которую указывает этот указатель ?
numcp имеет тип int(*)(char*, char*), а strcmp int(*)(const char*, const char*)
а то время как qsort хочет int(*)(void*, void*)
поэтому и нужно сначала приведение типов сделать

Re: Вопросы и ответы по программированию.

Добавлено: 20.10.2011, 18:56
nikit-xxx
Pr0Ger
спасибо, теперь картина проясняется: первая пара розовых скобок -- приведение типов выражения, которое получится во второй паре розовых скобок.

Собственно, как теперь найти общий язык с компилятором, чтобы он понял что в 23-ей строке требуется сделать приведение типов, и не ругался на неё?
Пробовал запускать компилятор с флагом -ansi, т. к. сие присутствует в названии книжки, но всё равно выдаёт то же предупреждение "warning: pointer type mismatch in conditional expression"
nikit-xxx писал(а):по какой-то причине разрабы GCC запретили обобщение указателя при помощи void*
это верно?

Re: Вопросы и ответы по программированию.

Добавлено: 20.10.2011, 19:43
Pr0Ger
nikit-xxx
вбил бы чей ошибку в гугл, первая ссылка на stackoverflow, где как раз вопрос про этот пример, откуда идет ссылка на другой вопрос, где как раз есть ответ, с объяснением

Re: Вопросы и ответы по программированию.

Добавлено: 21.10.2011, 01:29
MOZGIII
nikit-xxx
Замени всю строку на:

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

(numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp));
Кеп? %)
Компилятор не понимает что ты хочешь сделать, т.к. ( ... ? ... : ... ) - он вообще не знает что эта штука будет возвращать - она не типизированная. От этого и варнинг (у меня, gcc version 4.5.2 (GCC), тоже mingw, правда с моими примочками).

PS: дада, наконец-то, теперь я шарю и в сях xD

Re: Вопросы и ответы по программированию.

Добавлено: 21.10.2011, 11:04
nikit-xxx
фикс вариант 1

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

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(void *, void *));
int numcp(const char *, const char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines; /*кол-во считанных строк*/
	int numeric = 0; /*1 если числовая сортировка*/

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(void *, void *))(numeric ? numcp : strcmp));
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sort\n");
		return 1;
	}
}


/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	/*ничего не делать, если в массиве*/
		return;			/*меньше двух элементов*/
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(const char *s1, const char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%s\n", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c == '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 /*объём имеющейся памяти*/

static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/

char *alloc(int n) /*возвращает указатель на n символов*/
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
		allocp += n;
		return allocp - n; /*старый p*/
	} else /*недостаточно места в буфере*/
		return 0;
}
фикс вариант 2

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

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(const void *, const void *));
int numcp(const char *, const char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines; /*кол-во считанных строк*/
	int numeric = 0; /*1 если числовая сортировка*/

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				(int (*)(const void *, const void *))(numeric ? numcp : strcmp));
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sort\n");
		return 1;
	}
}


/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(const void *, const void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	/*ничего не делать, если в массиве*/
		return;			/*меньше двух элементов*/
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(const char *s1, const char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%s\n", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c == '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 /*объём имеющейся памяти*/

static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/

char *alloc(int n) /*возвращает указатель на n символов*/
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
		allocp += n;
		return allocp - n; /*старый p*/
	} else /*недостаточно места в буфере*/
		return 0;
}
фикс вариант от MOZGIII

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

#include <stdio.h>
#include <string.h>

#define MAXLINES 5000 /* максимальное число строк */
char *lineptr[MAXLINES]; /* указатели на строки текста */

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort_(void *lineptr[], int left, int right,
		int(*comp)(void *, void *));
int numcp(char *, char *);

/*сортировка строк из входного потока*/
main(int argc, char *argv[])
{
	int nlines; /*кол-во считанных строк*/
	int numeric = 0; /*1 если числовая сортировка*/

	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
		qsort_((void **) lineptr, 0, nlines-1,
				numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp);
		writelines(lineptr, nlines);
		return 0;
	}else{
		printf("input too big to sort\n");
		return 1;
	}
}


/*qsort_: сортировка v[left] ... v[right] в порядке возрастания*/
void qsort_(void *v[], int left, int right,
		int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int i, int j);

	if (left >= right)	/*ничего не делать, если в массиве*/
		return;			/*меньше двух элементов*/
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left+1; i<= right; i++)
		if((*comp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort_(v, left, last-1, comp);
	qsort_(v, last+1, right, comp);
}

#include <stdlib.h>
/*numcp: сравнение строк s1 и s2  по числовым значениям*/
int numcp(char *s1, char *s2)
{
	double v1, v2;

	v1 = atof(s1);
	v2 = atof(s2);
	if (v1 < v2)
		return -1;
	else if (v1 > v2)
		return 1;
	else
		return 0;
}

void swap(void *v[], int i, int j)
{
	void *temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

#define MAXLEN 1000
int getline(char*, int);
char *alloc(int);

/*readlines: считывание строк из входного потока*/
int readlines(char *lineptr[], int maxlines)
{
	int len, nlines;
	char *p, line[MAXLEN];

	nlines = 0;
	while ((len = getline(line, MAXLEN)) >0)
		if(nlines >= maxlines || (p = alloc(len)) == NULL)
			return -1;
		else {
			line[len-1] = '\0';/*удаление конца строки*/
			strcpy(p, line);
			lineptr[nlines++] = p;
		}
	return nlines;
}

/*writelines: вывод в выходной поток*/
void writelines(char *lineptr[], int nlines)
{
	int i;

	for(i = 0; i< nlines; i++)
		printf("%s\n", lineptr[i]);
}

/*getline: считывает строку в s, возвращает её длину*/
int getline(char s[], int lim)
{
	int c, i;

	for (i = 0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c == '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	return i;
}

#define ALLOCSIZE 10000 /*объём имеющейся памяти*/

static char allocbuf[ALLOCSIZE]; /*буфер памяти для alloc*/
static char *allocp = allocbuf; /*Следующая свободная позиция*/

char *alloc(int n) /*возвращает указатель на n символов*/
{
	if (allocbuf + ALLOCSIZE - allocp >= n) { /*есть место*/
		allocp += n;
		return allocp - n; /*старый p*/
	} else /*недостаточно места в буфере*/
		return 0;
}
Pr0Ger, MOZGIII, спасибо, теперь у меня есть 3 варианта, в которых компилятор не ругается, 2-й более-менее понятен.

Не ясно, почему, если функции qsort_(); в 4-м аргументе нужен указатель comp такого вида int(*comp)(void *, void *), и мы приводим его к этому виду, но
если одна из приводимых функций strcmp(const char *, const char *); а другая numcp(char *, char *); то компилятор ругается,
а если же обе таковы strcmp(const char *, const char *); numcp(const char *, const char *); то компилится нормально(1-й вариант).

MOZGIII
вообще не знает что эта штука будет возвращать - она не типизированная
в исходном варианте её пытаются привести к нужному типу (int (*)(void *, void *)), но почему-то это компилятор считает неправильным


Не пойму разницу [с точки зрения компилятора]

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

(int (*)(void *, void *))(numeric ? numcp : strcmp) //исходный вар-т, 4-й аргумент: преобразовать к нужному типу указатель, полученный после условного оператора : ?

numeric ? (int (*)(void *, void *))numcp : (int (*)(void *, void *))strcmp //в 4-й аргумент направить уже преобразованный к нужному типу ук-ль
по смыслу вроде одинаковые вещи, в 1-м случае результат, получившийся после действия условного оператора приводится к нужному типу, а во 2-м аргументы условного оператора преобразуются к нужному типу.

Re: Вопросы и ответы по программированию.

Добавлено: 21.10.2011, 19:04
Deus_Ex_Machina
nikit-xxx
MOZGIII писал(а):Компилятор не понимает что ты хочешь сделать, т.к. ( ... ? ... : ... ) - он вообще не знает что эта штука будет возвращать - она не типизированная.
Компилятор на слово тебе верить не станет, вдруг то, что вернет ?:, нельзя будет привести к тому, что ты от него требуешь.

Re: Вопросы и ответы по программированию.

Добавлено: 22.10.2011, 17:32
nikit-xxx
Спасибо всем ответившим, теперь понял так:
Компилятор ругается на шаге, когда просматривает типы(а они различаются) возможных результатов, которые может вернуть ? :, здесь он ещё не знает, что тип результата мы собираемся привести к нужному. То есть он защищает от ситуации, когда в зависимости от истинности/ложности проверочного_выражения мы бы получали результаты разных типов. Исходный вариант должен работать без ошибок(несмотря на warning), т. к. тип результата мы приводим к нужному.

Re: Вопросы и ответы по программированию.

Добавлено: 20.11.2011, 17:33
EvgenKo423
Доброго времени суток, господа кодеры. У меня следующий вопрос: как можно модифицировать библиотеку игры, чтобы из нее вызывалась функция из моей собственной библиотеки? Вообще как создатели эмулей модифицируют игровые библиотеки??

Re: Вопросы и ответы по программированию.

Добавлено: 21.11.2011, 19:36
Deus_Ex_Machina
Нужно написать свою библиотеку, где для нужных функций будут вызываться свои, а для остальных будет идти обращение к оригинальному длл.

Re: Вопросы и ответы по программированию.

Добавлено: 21.11.2011, 19:45
EvgenKo423
А библиотека че сама к игре подключится от того что я ее просто в папку закину?????
Наверно надо вызывать функции своей библиотеки из модифицированной игровой? Хотя бы одну.....

Re: Вопросы и ответы по программированию.

Добавлено: 21.11.2011, 19:47
Monk
Заменяешь игровую DLL своей, а твоя уже адресует запросы реальной + творит твои темные дела. Любой чит на кс16 в целом думаю тебе поможет.

Re: Вопросы и ответы по программированию.

Добавлено: 24.11.2011, 21:18
EvgenKo423
Возникают какие-то странные ошибки.....
Я начал с простого:
1. Скачал последние реверсы библиотек стима (от 17 ноября)
2. Создал свою библиотеку steam_api.dll с простой перекрывающей функцией

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

S_API bool STEAM_CALL SteamAPI_InitSafe()
{
	printf("InitSafe called!!!");

	return true;
}
3. Заменил оригинал, получил "Точка входа в процедуру SteamAPI_GetSteamInstallPath не найдена в библиотеке DLL steam_api.dll"
4. Прописал функцию из ошибки в экспорт
steam_api.def:

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

LIBRARY "steam_api"

EXPORTS
SteamAPI_GetSteamInstallPath

5. Повторял пункты 3 и 4 пока не получил следующую странную ошибку при компиляции:

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

1>steam_api.def : error LNK2001: unresolved external symbol SteamAPI_UseBreakpadCrashHandler
1>E:\CSSServer\VoiDeD-open-steamworks-16ab5b54c3e3\Release\steam_api.lib : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.
И как мне это понимать??? :dash: Сервер запрашивает у меня функцию, которая описана в Steamclient.h, но почему-то отсутствует в реверсе steam_api.lib.......

Re: Вопросы и ответы по программированию.

Добавлено: 27.11.2011, 08:15
andreil
EvgenKo423
Для правильной загрузки тебе надо описать не 1, а ВСЕ экспортируемые функции данной библиотеки.

Re: Вопросы и ответы по программированию.

Добавлено: 27.11.2011, 18:05
EvgenKo423
Я про то, что в реверсе есть не все функции