Автор работы: Пользователь скрыл имя, 23 Января 2012 в 11:07, контрольная работа
Появление мультипрограммирования привело к росту эффективности работы процессора. Суть его в том, что пока одно программа выполняет ввод/вывод, ЦП не простаивает, а выполняет другую программу. Когда ввод/вывод заканчивается ЦП снова выполняет 1-ую программу. При этом каждая программа загружается в свой участок памяти, называемой разделом и не должна влиять на выполнение других программ.
Если
бы мир был совершенен, то программистам
не пришлось бы беспокоиться о согласовании
интерфейсов функций при
По умолчанию в Visual C++ интерфейсы функций согласуются по правилам C++. Это значит, что параметры заносятся в стек справа налево, вызывающая программа отвечает за их удаление из стека при выходе из функции и расширении ее имени. Расширение имен (name mangling) позволяет редактору связей различать перегруженные функции, т.е. функции с одинаковыми именами, но разными списками аргументов. Однако в старой библиотеке С функции с расширенными именами отсутствуют.
Хотя все остальные правила вызова функции в С идентичны правилам вызова функции в C++, в библиотеках С имена функций не расширяются. К ним только добавляется впереди символ подчеркивания (_).
Если необходимо подключить библиотеку на С к приложению на C++, все функции из этой библиотеки придется объявить как внешние в формате С:
extern "С" int MyOldCFunction(int myParam);
Объявления
функций библиотеки обычно помещаются
в файле заголовка этой библиотеки,
хотя заголовки большинства
extern "С" { #include "MyCLib.h" }
В программах для старых версий Windows использовались также соглашения о вызове функций языка PASCAL для функций Windows API. В новых программах следует использовать модификатор winapi, преобразуемый в _stdcall. Хотя это и не стандартный интерфейс функций С или C++, но именно он используется для обращений к функциям Windows API. Однако обычно все это уже учтено в стандартных заголовках Windows.
При запуске приложение пытается найти все файлы DLL, неявно подключенные к приложению, и поместить их в область оперативной памяти, занимаемую данным процессом. Поиск файлов DLL операционной системой осуществляется в следующей последовательности.
Если библиотека DLL не обнаружена, приложение выводит диалоговое окно с сообщением о ее отсутствии и путях, по которым осуществлялся поиск. Затем процесс отключается.
Если нужная библиотека найдена, она помещается в оперативную память процесса, где и остается до его окончания. Теперь приложение может обращаться к функциям, содержащимся в DLL.
Вместо того, чтобы Windows выполняла динамическое связывание с DLL при первой загрузке приложения в оперативную память, можно связать программу с модулем библиотеки во время выполнения программы (при таком способе в процессе создания приложения не нужно использовать библиотеку импорта). В частности, можно определить, какая из библиотек DLL доступна пользователю, или разрешить пользователю выбрать, какая из библиотек будет загружаться. Таким образом можно использовать разные DLL, в которых реализованы одни и те же функции, выполняющие различные действия. Например, приложение, предназначенное для независимой передачи данных, сможет в ходе выполнения принять решение, загружать ли DLL для протокола TCP/IP или для другого протокола.
Первое, что необходимо сделать при динамической загрузке DLL, - это поместить модуль библиотеки в память процесса. Данная операция выполняется с помощью функции ::LoadLibrary, имеющей единственный аргумент – имя загружаемого модуля. Соответствующий фрагмент программы должен выглядеть так:
HINSTANCE hMyDll; …… if((hMyDll=::LoadLibrary
(“MyDLL”))==NULL) { /* не удалось загрузить DLL */ }
else { /* приложение имеет право
пользоваться функциями DLL через hMyDll */ }
Стандартным расширением файла библиотеки Windows считает .dll, если не указать другое расширение. Если в имени файла указан и путь, то только он будет использоваться для поиска файла. В противном случае Windows будет искать файл по той же схеме, что и в случае неявно подключенных DLL, начиная с каталога, из которого загружается exe-файл, и продолжая в соответствии со значением PATH.
Когда
Windows обнаружит файл, его полный путь
будет сравнен с путем
Если файл обнаружен и библиотека успешно загрузилась, функция ::LoadLibrary возвращает ее дескриптор, который используется для доступа к функциям библиотеки.
Перед
тем, как использовать функции библиотеки,
необходимо получить их адрес. Для этого
сначала следует
// тип PFN_MyFunction будет объявлять указатель
на функцию,
// принимающую указатель на символьный буфер
и выдающую значение типа int typedef int
(WINAPI *PFN_MyFunction)(char *);
…… PFN_MyFunction pfnMyFunction;
Затем следует получить дескриптор библиотеки, при помощи которого и определить адреса функций, например адрес фунции с именем MyFunction:
hMyDll=::LoadLibrary(“MyDLL”)
pfnMyFunction=(
…… int iCode=(*pfnMyFunction)(“Hello”
Адрес функции определяется при помощи функции ::GetProcAddress, ей следует передать имя библиотеки и имя функции. Последнее должно передаваться в том виде, в котором эксаортируется из DLL.
Можно также сослаться на функцию по порядковому номеру, по которому она экспортируется (при этом для создания библиотеки должен использоваться def-файл, об этом будет рассказано далее):
pfnMyFunction=(PFN_
(hMyDll, MAKEINTRESOURCE(1));
После завершения работы с библиотекой динамической компоновки, ее можно выгрузить из памяти процесса с помощью функции ::FreeLibrary:
Приведем теперь исходный код простого приложения, которое использует функцию MyFunction из библиотеки MyDLL.dll:
#include <windows.h> #include “MyDLL.h”int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow) { int iCode=MyFunction(“Hello”);
return 0; }
Эта программа выглядит как обычная программ для Windows, чем она в сущности и является. Тем не менее, следует обратить внимание, что в исходный ее текст помимо вызова функции MyFunction из DLL-библиотеки включен и заголовочный файл этой библиотеки MyDLL.h. Также необходимо на этапе компоновки приложения подключить к нему библиотеку импорта MyDLL.lib (процесс неявного подключения DLL к исполняемому модулю).
Чрезвычайно важно понимать, что сам код функции MyFunction не включается в файл MyApp.exe. Вместо этого там просто имеется ссылка на файл MyDLL.dll и ссылка на функцию MyFunction, которая находится в этом файле. Файл MyApp.exe требует запуска файла MyDLL.dll.
Заголовочный файл MyDLL.h включен в файл с исходным текстом программы MyApp.c точно так же, как туда включен файл windows.h. Включение библиотеки импорта MyDLL.lib для компоновки аналогично включению туда всех библиотек импорта Windows. Когда програма MyApp.exe работает, она подключается к библиотеке MyDLL.dll точно так же, как ко всем стандартным динамически подключаемым библиотекам Windows.
Приведем теперь полностью исходный код простого приложения, которое использует функцию MyFunction из библиотеки MyDLL.dll, используя динамическую загрузку библиотеки:
#include <windows.h> typedef int
(WINAPI *PFN_MyFunction) (char *); int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{ HINSTANCE hMyDll;
if((hMyDll=
PFN_
pfnMyFunctio
GetProcAddress(hMyDll,”
int iCode=(*pfnMyFunction)(“Hello”
FreeLibrary(
Теперь, познакомившись с принципами работы библиотек DLL в приложениях, рассмотрим способы их создания. При разработке приложении функции, к которым обращается несколько процессов, желательно размещать в DLL. Это позволяет более рационально использовать память в Windows.
Проще всего создать новый проект DLL с помощью мастера AppWizard, который автоматически выполняет многие операции. Для простых DLL, таких как рассмотренные в этой главе, необходимо выбрать тип проекта Win32 Dynamic-Link Library. Новому проекту будут присвоены все необходимые параметры для создания библиотеки DLL. Файлы исходных текстов придется добавлять к проекту вручную.
Если же планируется в полной мере использовать функциональные возможности MFC, такие как документы и представления, или намерены создать сервер автоматизации OLE, лучше выбрать тип проекта MFC AppWizard (dll). В этом случае, помимо присвоения проекту параметров для подключения динамических библиотек, мастер проделает некоторую дополнительную работу.
Задание: Создайте командный файл резервного копирования файлов с определенными расширениями из разных каталогов с возможностью создания резервного каталога, если его нет в системе.
Ход выполнения работы:
echo on
IF NOT exist kp md kp - команда создаст каталог kp при условии что его нету в системе.
cd kp -
md s –
md f -
cd ..-
copy project\*.doc kp\s -
copy project\*.txt kp\f
copy project1\*.doc kp\s
copy Project1\*.txt kp\f
При
выполнении этой контрольной работы
я узнал что такое