Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Во время обработки параметров обратный вызов можно инициировать в трех точках: до начала обработки, при нахождении параметра в таблице для данного обратного вызова и после завершения обработки. Это дает библиотекам возможность инициализировать любые необходимые им структуры (включая данные, определяемые членом descrip
), и выполнять любые служебные действия, которые могут понадобиться после завершения обработки (например, очищать динамическую память, выделенную для члена descrip
). Они всегда вызываются при нахождении параметра, однако в таблице параметров необходимо указать, что их нужно вызывать в двух других местах. Чтобы сделать это, значения POPT_CBFLAG_PRE
или POPT_CBFLAG_POST
(или оба) должны объединяться битовым "ИЛИ" со значением POPT_ARG_CALLBACK
, присвоенным члену arg
структуры, которая определяет обратный вызов.
Далее показан прототип, который следует использовать для определения функции обратного вызова:
void callback(poptContext con, enum poptCallbackReason reason,
const struct poptOption * opt, const char * arg,
const void * data);
Первый параметр представляет содержимое, синтаксический анализ которого будет выполнен во время инициирования обратного вызова. Следующим параметров является POPT_CALLBACK_REASON_PRE
, если обработка параметра еще не началась, POPT_CALLBACK_REASON_POST
, если обработка параметров завершена, или POPT_CALLBACK_REASON_OPTION
, если в таблице для данного обратного вызова был обнаружен параметр. Если этот параметр является последним, то аргумент opt будет указывать на элемент таблицы параметров для обнаруженного параметра, а аргумент arg
будет указывать на строку, определяющую аргумент для данного параметра. Если ожидается аргумент, не представленный в виде строки, обратный вызов будет отвечать за проверку типа и преобразование аргумента. Последний параметр для обратного вызова, data
, представляет собой значение поля descrip
в элементе таблицы параметров, который задает обратный вызов.
Ниже показан пример библиотеки, которая использует вложенную таблицу popt
и обратные вызовы для синтаксического анализа некоторых параметров командной строки. Структура данных инициализируется до начала синтаксического анализа командной строки, а затем отображаются последние значения.
1: /* popt-lib.с */
2:
3: #include
4: #include
5:
6: struct params {
7: int height, width;
8: char*fg,*bg;
9: };
10:
11: static void callback(poptContext con,
12: enum poptCallbackReason reason,
13: const struct poptOption * opt,
14: const char * arg,
15: const void * data);
16:
17: /* Здесь сохраняются переменные, которые прошли синтаксический анализ. Обычно
18: глобальные переменные использовать не рекомендуется, зато работать с ними проще.*/
19: struct params ourParam;
20:
21: struct poptOption libTable[] = {
22: { NULL, '\0',
23: POPT_ARG_CALLBACK | POPT_CBFLAG_PRE | POPT_CBFLAG_POST,
24: callback, '\0', (void *) &ourParam, NULL },
25: { "height", 'h', POPT_ARG_STRING, NULL, '\0', NULL, NULL },
26: { "width", 'w', POPT_ARG_STRING, NULL, '\0', NULL, NULL },
27: { "fg", 'f', POPT_ARG_STRING, NULL, '\0', NULL, NULL },
28: { "bg", 'b', POPT_ARG_STRING, NULL, '\0', NULL, NULL },
29: { NULL, '\0', POPT_ARG_NONE, NULL, '\0', NULL, NULL }
30: };
31:
32: static void callback(poptContext con,
33: enum poptCallbackReason reason,
34: const struct poptOption * opt,
35: const char * arg,
36: const void * data) {
37: struct params * p = (void *) data;
38: char * chptr = NULL;
39:
40: if (reason == POPT_CALLBACK_REASON_PRE) {
41: p->height = 640;
42: p->width = 480;
43: p->fg = "white";
44: p->bg = "black";
45: } else if (reason == POPT_CALLBACK_REASON_POST) {
46: printf("используется высота %d ширина %d передний план %s фон %s\n",
47: p->height, p->width, p->fg, p->bg);
48:
49: } else {
50: switch (opt->shortName) {
51: case 'h': p->height = strtol(arg, &chptr, 10); break;
52: case 'w': p->width = strtol(arg, &chptr, 10); break;
53: case 'f' : p->fg = (char *) arg; break;
54: case 'b': p->bg = (char *) arg; break;
55: }
56:
57: if (chptr && *chptr) {
58: fprintf(stderr, "для %s ожидался числовой аргумент\n",
59: opt->longName);
60: exit(1);
61: }
62: }
63: }
64:
Программа, для которой необходимо обеспечить эти аргументы командной строки, должна включать одну дополнительную строку в своей таблице popt
. Обычно этой строкой является макрос, задаваемый в заголовочном файле (подобно тому, как реализуется POPT_AUTOHELP
), но в целях упрощения в данном примере мы просто явным образом покажем эту строку.
1: /* popt-nest.c */
2:
3: #include
4:
5: /* Обычно это объявление осуществляется в заголовочном файле */
6: extern struct poptOption libTable[];
7:
8: int main(int argc, const char * argv[]) {
9: poptContext optCon;
10: int rc;
11: struct poptOption options[] = {
12: { "app1", '\0', POPT_ARG_NONE, NULL, '\0' },
13: { NULL, '\0', POPT_ARG_INCLUDE_TABLE, libTable,
14: '\0', "Nested:", }
15: POPT_AUTOHELP
16: { NULL, '\0', POPT_ARG_NONE, NULL, '\0' }
17: };
18:
19: optCon = poptGetContext("popt-nest", argc, argv, options, 0);
20:
21: if ((rc = poptGetNextOpt (optCon)) < -1) {
22: fprintf(stderr, "%s: %s\n",
23: poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
24: poptStrerror(rc));
25: return 1;
26: }
27:
28: return 0;
29: }
26.4. Обработка ошибок
Каждая из функций popt
, которая может возвращать ошибки, возвращает целочисленные значения. В случае возникновения ошибки возвращается отрицательный код. В табл. 26.2 перечислены коды возможных ошибок. После таблицы дается подробное обсуждение каждой ошибки.
Таблица 26.2. Коды ошибок popt
Код ошибки | Описание |
---|---|
POPT_ERROR_NOARG |
Отсутствует аргумент для данного параметра. |
POPT_ERROR_BADOPT |
Невозможно проанализировать синтаксис аргумента параметра. |
POPT_ERROR_OPTSTOODEEP |
Слишком глубокое вложение замещений имени параметра. |
POPT_ERROR_BADQUOTE |
Несоответствие кавычек. |
POPT_ERROR_BADNUMBER |
Невозможно преобразовать параметр в число. |
POPT_ERROR_OVERFLOW |
Данное число слишком большое или слишком маленькое. |
POPT_ERROR_NOARG |
Параметр, для которого требуется аргумент, был определен в командной строке, однако аргумент не был предоставлен. Эта ошибка может быть возвращена только функцией poptGetNextOpt() . |
POPT_ERROR_BADOPT |
Параметр был определен в массиве argv , однако его нет в таблице параметров. Эта ошибка может быть возвращена только функцией poptGetNextOpt() . |
POPT_ERROR_OPTSTOODEEP |
Совокупность замещений имени параметра имеет большую глубину вложений. На данный момент popt отслеживает параметры только до 10 уровня, чтобы избежать возникновения бесконечной рекурсии. Эту ошибку возвращает только функция poptGetNextOpt() . |
POPT_ERROR_BADQUOTE |
В строке, прошедшей синтаксический анализ, было обнаружено несоответствие кавычек (например, была обнаружена только одна одинарная кавычка). Эту ошибку могут возвращать функции poptParseArgvString() , poptReadConfigFile() и poptReadDefaultConfig() . |
POPT_ERROR_BADNUMBER |
Преобразование строки в число ( int или long ) не было выполнено вследствие того, что строка содержит нецифровые символы. Эта ошибка возникает в том случае, когда функция poptGetNextOpt() обрабатывает аргумент типа РOРТ_ARG_INT или POPT_ARG_LONG . |
POPT_ERROR_OVERFLOW |
Преобразование из строки в число не было выполнено вследствие того, что число было слишком большим или слишком маленьким. Подобно ошибке POPT_ERROR_BADNUMBER , эта ошибка может возникнуть только в том случае, если функция poptGetNextOpt() обрабатывает аргумент типа РОРТ_ARG_INT или POPT_ARG_LONG . |
POPT_ERROR_ERRNO |
Системный вызов был возвращен вместе с ошибкой, а errno до сих пор содержит ошибку из системного вызова. Эту ошибку могут возвращать функции poptReadConfigFile() и poptReadDefaultConfig() . |
Приложения могут генерировать качественные сообщения об ошибках с помощью следующих двух функций.
Читать дальшеИнтервал:
Закладка: