Студопедия — ТЕОРЕТИЧЕСКАЯ ЧАСТЬ. Библиотека представляет собой набор функций [1]
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

ТЕОРЕТИЧЕСКАЯ ЧАСТЬ. Библиотека представляет собой набор функций [1]






Библиотека представляет собой набор функций [1]. Когда программа обращается к библиотечной функции, редактор связей находит эту функцию и добавляет ее код в программу. Исполняемый файл содержит только те функции, которые используются программой, а не все библиотечные функции [1].

Библиотека называется статически подключаемой, если код, содержащийся в ней, непосредственно компонуется к основной программе. Такая библиотека содержит набор уже откомпилированных объектных файлов с функциями и данными. Библиотеки целесообразно применять для хранения функций, которые могут быть использованы при создании различных программ, реализующих распространенные алгоритмы и осуществляющих поддержку и обработку распространенных структур данных.

Механизм компиляции и компоновки программы на языке C требует, помимо наличия откомпилированного библиотечного модуля, присутствия заголовочных файлов (h -файлов), содержащих объявления структур данных и прототипы функций, предоставляемых библиотекой.

Среда Visual Studio 2010 использует расширение .lib для библиотечных модулей. При создании статически подключаемой библиотеки в среде Visual Studio 2010 необходимо выполнить следующую последовательность действий: разработать новый проект (пункты главного меню: File ® New ® Project), выбрать тип проекта в списке Project types: Win32 ® Win32 Project и задать имя проекта, например containers. При необходимости можно указать место его расположения, используя кнопку Browse. В результате должна получиться форма, показанная на рис. 20.1.


 


Рис. 20.1. Окно создания проекта с подключаемой библиотекой

Далее следует нажать кнопку OK. Появится форма с заголовком «Win32 Application Wizard – containers».

На закладке Application Settings мастера создания проекта нужно сделать следующие настройки:

– установить Application type (тип приложения) в Static Library (статическая библиотека);

– снять флажок с пункта Precompiled header (прекомпилированный заголовок).

После установки настроек появится форма (рис. 20.2), которая представляет собой пустой проект статической библиотеки.


 


Рис. 20.2. Настройка приложения статической библиотеки

Для завершения настройки закладки Application Settings следует нажать кнопку Finish. Появится форма, показанная на рис. 20.3.


 


Рис. 20.3. Окно пустого проекта для статической библиотеки

Добавление файлов в проект библиотеки производится стандартным образом, как и для проекта Win32 Console Application. В соответствии с рис. 20.3 существующие файлы, которые будут использоваться в многофайловом проекте, могут быть подключены при установке курсора мыши на папках Header Files, Resource Files, Source Files с последующим нажатием правой клавиши и выбором пункта меню Add, а именно Existing Item.

Для подключения h -файлов(*.h) следует обратиться к папке проекта Header Files, для с -файлов, (*.с,) использовать папку Source Files.

Выполним подключение существующих файлов stack.h / stack.c, queue.h / queue.c, реализующих в простейшем виде две важные структуры данных – стек и очередь.

Статическая библиотека является не исполняемой программой, а только механизмом для хранения подпрограмм, поэтому среди ее функций не должно быть функции main().

После подключения файлов получится форма с открытой программой файла stack.h (рис. 20.4).


 


Рис. 20.4. Окно проекта статической библиотеки с подключенными

файлами

До выполнения компиляции необходимо произвести настройку параметров компилятора так же, как и для проекта Win32 Console Application. В частности, из пункта меню Project следует выбрать containers Properties (Alt + F7). После раскрытия узла Configuration Properties появится форма, показанная на рис. 20.5.


 


Рис. 20.5. Обращение к странице свойств проекта

Сначала нужно обратиться к пункту General, затем – к закладке Character Set, в которой выбрать Use Multy-Byte Character Set (как и при настройке консольного приложения). Далее необходимо раскрыть узел С/С++, в котором обратиться к закладке Code Generation, затем в другой панели закладка Enable C++ Exceptions устанавливается в положение No (как и при настройке консольного приложения).

Результат установки свойств закладки Language представлен на рис. 20.6.


 


Рис. 20.6. Установка свойств закладки Language

Режим работы языка С в MS Visual Studio устанавливается на закладке Advanced (рис. 20.7).


 


Рис. 20.7. Результат выбора компиляции языка С

Важным моментом, на который требуется обратить внимание, является версия используемой библиотеки времени выполнения (runtime library). Библиотека времени выполнения содержит функции стандартной библиотеки языка С, а также некоторое вспомогательное окружение, которое позволяет программе, написанной на языке С, выполняться в ОС Windows. Версии библиотеки времени выполнения для статически подключаемой библиотеки и для программы, ее использующей, должны совпадать. Поэтому статически подключаемую библиотеку часто компилируют в различных конфигурациях, каждая из которых использует свою версию библиотеки времени выполнения. В примере будем использовать многопоточную отладочную версию библиотеки, подключаемую к программе динамически (Multi-threaded Debug DLL) для отладочной сборки библиотеки, и многопоточную версию, подключаемую динамически (Multi-threaded DLL), для конечной версии программы.

Тип используемой библиотеки времени выполнения выбирается на странице свойств [ C/C++ ]|[ Code Generation ]|[ Runtime Library ]. Он должен совпадать с типом, выбранным при настройке свойств библиотеки, в данном случае Multy-Threaded Debug DLL(\MDd).

Результат выбора типа библиотеки показан на рис. 20.8 (по умолчанию).


 


Рис. 20.8. Установка типа библиотеки времени выполнения

Подключение программных файлов осуществляется обычными средствами, рассмотренными, например, в предыдущей теме. Программный код каждого из подключенных файлов можно вывести (двойным щелчком мыши) в окно редактирования. Для примера выведем код файла stack.h. Результат подключения файлов stack.h/stack.c и queue.h/queue.c, показан на рис. 20.9.


 


Рис. 20.9. Форма с подключенными файлами

После выполнения настроек компилятора необходимо выполнить настройки библиотекаря (Librarian) на вкладке после узла С/С++. Страница свойств библиотекаря содержит несколько настроек, из которых основной является имя создаваемой библиотеки. По умолчанию имя библиотеки совпадает с именем проекта. В этом случае следует оставить без изменения имеющиеся настройки закладки General узла Librarian. На закладке General в пункте Output File по умолчанию установлено $OutDir$(TargetName)$(TargetExt), что оставляем без изменения.

Открывающаяся страница свойств представлена на рис. 20.10.


 

 


Рис. 20.10. Страница свойств Librarian – General – Output File

Настройка свойств Librarian завершается нажатием клавиш «Применить» и «OK».

После осуществления всех настроек выполняется компиляция и сборка библиотеки. В процессе компиляции модули, входящие в состав библиотеки (файлы с расширением .c), сначала обрабатываются препроцессором языка C, затем компилируются независимо друг от друга. В результате получается набор файлов с расширением .obj, содержащих скомпилированный код библиотечных функций. Затем полученный набор объектных файлов (с расширением .obj) объединяется в библиотечный модуль (файл с расширением .lib).

Процесс сборки проекта статической библиотеки запускается из пункта меню Build ® Build containers. Результат выбора показан на рис. 20.11.


 


Рис. 20.11. Запуск компиляции и сборки библиотеки

В процессе сборки библиотеки компилятор и библиотекарь (Librarian) выводят в окно сообщений (Output) среды Visual Studio диагностическую информацию, содержащую результаты компиляции каждого из модулей, подключенных к проекту статической библиотеки, возможные предупреждения компилятора и конечную статистику (например, количество ошибок и предупреждений) сборки библиотеки (рис. 20.12).

В результате произведенной компиляции получаем папку с именем созданной библиотеки (containers), где в папке Debug располагается двоичный объектный библиотечный модуль – файл с расширением .lib. Для данного случая это файл containers.lib.


 


Рис. 20.12. Окно с сообщением об успешной компиляции библиотеки

Программные коды подключаемых файлов

// file stack.h #ifndef STACK_H__ #define STACK_H__ /// by default a stack reserves space for 16 items #define STACK_INITIAL_CAPACITY 16 typedef struct stack { /// number of items in the stack int m_length; /// capacity of the stack int m_capacity; /// block of memory for the stack int *m_items; } stack_t; /// create a new stack and returns it stack_t *stack_create (int capacity); /// destroys the stack and frees resources void stack_destroy (stack_t *stack); /// pushes an item into the stack int stack_push (stack_t *stack, int item); /// pops the item from the stack int stack_pop (stack_t *stack); /// checks whether the stack is empty int stack_is_empty (stack_t *stack); #endif
 
// file stack.c #include <assert.h> #include <malloc.h> #include <stddef.h> #include "stack.h" static int stack_ensure_capacity (stack_t *stack, int capacity) { int capacityDesired; int *p; if (stack->m_capacity >= capacity) return 1; capacityDesired = stack->m_capacity * 2; p = realloc (stack->m_items, capacityDesired * sizeof (int)); if (!p) return 0; stack->m_items = p; stack->m_capacity = capacityDesired; return 1; } stack_t* stack_create (int capacity) { stack_t *result; if (capacity <= 0) capacity = STACK_INITIAL_CAPACITY; result = malloc (sizeof (stack_t)); if (!result) return NULL; result->m_items = malloc (capacity * sizeof (int)); if (!result->m_items) { free (result); return NULL; } result->m_capacity = capacity; result->m_length = 0; return result; } void stack_destroy (stack_t *stack) { assert (stack!= NULL); assert (stack->m_items!= NULL); free (stack->m_items); free (stack); } int stack_push (stack_t *stack, int item) { assert (stack!= NULL); assert (stack->m_capacity > 0); assert (stack->m_items!= NULL); if (!stack_ensure_capacity (stack, stack->m_length + 1)) return 0; stack->m_items[stack->m_length++] = item; return 1; } int stack_pop (stack_t *stack) { assert (!stack_is_empty (stack)); return stack->m_items[--stack->m_length]; } int stack_is_empty (stack_t *stack) { assert (stack!= NULL); return stack->m_length <= 0; }
 
// file queue.h #ifndef QUEUE_H__ #define QUEUE_H__ typedef struct queue_item { /// pointer to the next item in the queue struct queue_item *m_next; /// item data int m_item; } queue_item_t; typedef struct queue { /// number of items in the queue int m_length; /// first item in the queue struct queue_item *m_head; /// last items in the queue struct queue_item **m_tailnext; } queue_t; /// creates a new queue and returns it queue_t *queue_create (); /// destroys the queue and frees resources void queue_destroy (queue_t *queue); /// pushes an item into the queue adding it to the queue's tail int queue_push (queue_t *queue, int item); /// pops the item from the queue, removing it from the queue's head int queue_pop (queue_t *queue); /// checks whether the queue is empty int queue_is_empty (queue_t *queue); #endif
 
// file queue.c #include <assert.h> #include <malloc.h> #include <stddef.h> #include "queue.h" queue_t* queue_create () { queue_t *queue; queue = malloc (sizeof (queue_t)); if (!queue) return NULL; queue->m_head = NULL; queue->m_tailnext = &(queue->m_head); queue->m_length = 0; return queue; } void queue_destroy (queue_t *queue) { queue_item_t *p; assert (queue!= NULL); for (p = queue->m_head; p!= NULL; p = p->m_next) free (p); free (queue); } int queue_push (queue_t *queue, int item) { queue_item_t *p; assert (queue!= NULL); assert (queue->m_tailnext!= NULL); // create new queue item and insert it into tail p = malloc (sizeof (queue_item_t)); if (!p) return 0; p->m_next = NULL; p->m_item = item; *queue->m_tailnext = p; queue->m_tailnext = &(p->m_next); ++queue->m_length; return 1; } int queue_pop (queue_t *queue) { queue_item_t *p; assert (!queue_is_empty (queue)); // detach head and return the item p = queue->m_head; if (p) { int item = p->m_item; queue->m_head = p->m_next; // if the last one was removed than // we should reset our tail if (queue->m_tailnext == &(p->m_next)) queue->m_tailnext = &(queue->m_head); free (p); --queue->m_length; assert (queue->m_length >= 0); return item; } assert (1!= 1); // should not happen return 0; } int queue_is_empty (queue_t *queue) { assert (queue!= NULL); return queue->m_length <= 0; }

Для работы с библиотекой следует подготовить проект с главной функцией main(), в которой подключаются файлы, расположенные в созданной статической библиотеке, с помощью директивы #include. Для подключаемых файлов необходимо указать путь, где они расположены. Обычно это делается с помощью нотации "..\..\stack.h";, которая указывает, что файл stack.h находится на два уровня выше, чем функция main(), в которой он будет использоваться.

Настройка проекта с главной функцией main() выполняется при установке режима компиляции языка С системы MS Visual Studio 2010. Для этого в меню системы MS Visual Studio последовательно выбирается File ® New ® Project. Далее из списка типа проекта Project types также последовательно выбираются Visual C++ ® Win32 ® Win32 Console Application. В поле Name прописывается имя проекта, например Lab20. Далее осуществляется настройка проекта в режиме компиляции языка С (см. тему 1).

При настройке параметров компилятора дополнительно необходимо указать компилятору пути к заголовочным файлам stack.h и queue.h, содержащим объявления интерфейса созданной библиотеки containers. Это можно сделать в пункте Additional Include Directories (дополнительные каталоги с заголовочными файлами) на странице свойств [C/C++]|[General]. Затем указывается путь к папке containers, в которой находятся библиотечные файлы stack.h/stack.с и queue.h/queue.с в виде ..\..\containers\ containers.

Форма с установкой пути к созданной статической библиотеке показана на рис. 20.13.



Рис. 20.13. Установка пути к файлам созданной библиотеки

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

На странице свойств [Linker]|[Input] необходимо указать путь к объектному файлу библиотеки. Форма с установкой свойств компоновщика показана на рис. 20.14.


 


Рис. 20.14. Настройка компоновщика Linker–Input–Additional

Dependencies

После выполнения всех настроек можно компилировать программу и запускать ее на выполнение.

Проект с главной функцией main() и включенными заголовочными файлами из созданной библиотеки представлен на рис. 20.15.


 


Рис. 20.15. Форма с откомпилированным проектом

Программный код главной функции проекта

#include <stdio.h> #include <conio.h> #include "..\..\stack.h" #include "..\..\queue.h" int main (void) { int i; queue_t *q = queue_create(); stack_t *s = stack_create(-1); for (i = 0; i < 16; ++i) // заполнение стека stack_push (s, i); printf("\n Stack content:\n"); if (!stack_is_empty (s)) printf (" %3d\n", stack_pop (s)); stack_destroy (s); // разрушение стека for (i = 0; i < 14; ++i) // заполнение очереди queue_push (q, i); printf("\n Queue content:\n"); if (!queue_is_empty (q)) printf (" %3d\n", queue_pop (q)); queue_destroy (q); // разрушение очереди printf("\n\n Press any key: "); getch(); return 0; }


Результат выполнения программы приведен на рис. 20.16.

Рис. 20.16. Результат выполнения программы с файлами из библиотеки

 

 







Дата добавления: 2015-09-06; просмотров: 549. Нарушение авторских прав; Мы поможем в написании вашей работы!



Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Роль органов чувств в ориентировке слепых Процесс ориентации протекает на основе совместной, интегративной деятельности сохранных анализаторов, каждый из которых при определенных объективных условиях может выступать как ведущий...

Лечебно-охранительный режим, его элементы и значение.   Терапевтическое воздействие на пациента подразумевает не только использование всех видов лечения, но и применение лечебно-охранительного режима – соблюдение условий поведения, способствующих выздоровлению...

Тема: Кинематика поступательного и вращательного движения. 1. Твердое тело начинает вращаться вокруг оси Z с угловой скоростью, проекция которой изменяется со временем 1. Твердое тело начинает вращаться вокруг оси Z с угловой скоростью...

Принципы резекции желудка по типу Бильрот 1, Бильрот 2; операция Гофмейстера-Финстерера. Гастрэктомия Резекция желудка – удаление части желудка: а) дистальная – удаляют 2/3 желудка б) проксимальная – удаляют 95% желудка. Показания...

Ваготомия. Дренирующие операции Ваготомия – денервация зон желудка, секретирующих соляную кислоту, путем пересечения блуждающих нервов или их ветвей...

Билиодигестивные анастомозы Показания для наложения билиодигестивных анастомозов: 1. нарушения проходимости терминального отдела холедоха при доброкачественной патологии (стенозы и стриктуры холедоха) 2. опухоли большого дуоденального сосочка...

Studopedia.info - Студопедия - 2014-2024 год . (0.013 сек.) русская версия | украинская версия