Опубликован: 14.12.2010 | Уровень: для всех | Доступ: свободно

Лекция 21: Программы на языке С при использовании статически подключаемой библиотеки

< Лекция 20 || Лекция 21: 12345 || Лекция 22 >

Настройка проекта с главной функцией 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. Установка пути к файлам созданной библиотеки

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

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

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

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

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

Рис. 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");
	while (!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");
	
 while (!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. Результат выполнения программы с файлами из библиотеки

Задание

  1. Предусмотрите ввод чисел, помещаемых в очередь, с клавиатуры.
  2. Предусмотрите ввод чисел, помещаемых в стек, с клавиатуры. Ввод чисел выполните до заданного наперед символа, например, первой буквы фамилии пользователя.
  3. Видоизмените проект для хранения в стеке (и вывода содержимого на консоль) данных типа char.

Практическая часть

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

3 5 1 8 12 21 25.

Результат симметричного представления:

25 21 12 8 1 5 3 5 1 8 12 21 25.

Программный код решения примера состоит из двух файлов:

// Файл основного модуля проекта main.c
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include "xyx.h"

int main (void) {
	int i, n = 7;
	int M[] = {3, 5, 1, 8, 12, 21, 25};

	printf("\n Initial array:\n");
for (i = 0; i < n; ++i)
printf(" %3d", M[i]);

printf("\n\n New array:\n");
for (i = 0; i < (2*n-1); ++i)
printf(" %3d", *(xyx(M, n)+i));

	printf("\n\n Press any key: ");
	_getch();
	return 0;
}
// Подключаемый заголовочный файл xyx.h
// file xyx.h

int *xyx(int M[], int n);
// Подключаемый файл xyx.c
#include <stdlib.h>

int *xyx(int M[], int n) {
	int j, p = 2*n - 1;
	int *PTR;
	PTR = (int *)calloc(p,sizeof(int));
	for (j = 0; j < p; ++j)
PTR[j] = 0;

	for (j = 0; j < p; ++j) 
if (j < n) 
PTR[j] = M[(n-1) - j];
else 
PTR[j] = M[j - (n-1)];

return PTR; }

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

Результат симметричного преобразования массива

Рис. 20.17. Результат симметричного преобразования массива
< Лекция 20 || Лекция 21: 12345 || Лекция 22 >
Мухаммадюсуф Курбонов
Мухаммадюсуф Курбонов