Мультипрограммирование. Мультипрограммирование в системах разделения времени.. Библиотеки динамической компоновки DLL

Автор работы: Пользователь скрыл имя, 23 Января 2012 в 11:07, контрольная работа

Краткое описание

Появление мультипрограммирования привело к росту эффективности работы процессора. Суть его в том, что пока одно программа выполняет ввод/вывод, ЦП не простаивает, а выполняет другую программу. Когда ввод/вывод заканчивается ЦП снова выполняет 1-ую программу. При этом каждая программа загружается в свой участок памяти, называемой разделом и не должна влиять на выполнение других программ.

Содержимое работы - 1 файл

Кп.doc

— 163.00 Кб (Скачать файл)

      Если  бы мир был совершенен, то программистам  не пришлось бы беспокоиться о согласовании интерфейсов функций при подключении  библиотек — все они были бы одинаковыми. Однако мир далек от совершенства, и многие большие программы  написаны с помощью различных библиотек без C++.

      По  умолчанию в Visual C++ интерфейсы функций  согласуются по правилам C++. Это значит, что параметры заносятся в  стек справа налево, вызывающая программа  отвечает за их удаление из стека при  выходе из функции и расширении ее имени. Расширение имен (name mangling) позволяет редактору связей различать перегруженные функции, т.е. функции с одинаковыми именами, но разными списками аргументов. Однако в старой библиотеке С функции с расширенными именами отсутствуют.

      Хотя  все остальные правила вызова функции в С идентичны правилам вызова функции в C++, в библиотеках С имена функций не расширяются. К ним только добавляется впереди символ подчеркивания (_).

      Если  необходимо подключить библиотеку на С к приложению на C++, все функции  из этой библиотеки придется объявить как внешние в формате С:

         extern "С" int MyOldCFunction(int myParam);

      Объявления  функций библиотеки обычно помещаются в файле заголовка этой библиотеки, хотя заголовки большинства библиотек  С не рассчитаны на применение в проектах на C++. В этом случае необходимо создать копию файла заголовка и включить в нее модификатор extern "C" к объявлению всех используемых функций библиотеки. Модификатор extern "C" можно применить и к целому блоку, к которому с помощью директивы #tinclude подключен файл старого заголовка С. Таким образом, вместо модификации каждой функции в отдельности можно обойтись всего тремя строками:

         extern "С"   {   #include "MyCLib.h"  }

      В программах для старых версий Windows использовались также соглашения о вызове функций языка PASCAL для функций Windows API. В новых программах следует использовать модификатор winapi, преобразуемый в _stdcall. Хотя это и не стандартный интерфейс функций С или C++, но именно он используется для обращений к функциям Windows API. Однако обычно все это уже учтено в стандартных заголовках Windows.

      Загрузка неявно подключаемой DLL

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

  • Каталог, в котором находится ЕХЕ-файл.
  • Текущий каталог процесса.
  • Системный каталог Windows.

      Если  библиотека DLL не обнаружена, приложение выводит диалоговое окно с сообщением о ее отсутствии и путях, по которым осуществлялся поиск. Затем процесс отключается.

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

      Динамическая загрузка и выгрузка DLL

      Вместо  того, чтобы Windows выполняла динамическое связывание с DLL при первой загрузке приложения в оперативную память, можно связать программу с  модулем библиотеки во время выполнения программы (при таком способе в процессе создания приложения не нужно использовать библиотеку импорта). В частности, можно определить, какая из библиотек DLL доступна пользователю, или разрешить пользователю выбрать, какая из библиотек будет загружаться. Таким образом можно использовать разные DLL, в которых реализованы одни и те же функции, выполняющие различные действия. Например, приложение, предназначенное для независимой передачи данных, сможет в ходе выполнения принять решение, загружать ли DLL для протокола TCP/IP или для другого протокола.

      2.3. Загрузка обычной DLL

 

      Первое, что необходимо сделать при динамической загрузке DLL, - это поместить модуль библиотеки в память процесса. Данная операция выполняется с помощью  функции ::LoadLibrary, имеющей единственный аргумент – имя загружаемого модуля. Соответствующий фрагмент программы должен выглядеть так:

         HINSTANCE hMyDll;  ……  if((hMyDll=::LoadLibrary

      (“MyDLL”))==NULL) { /* не удалось загрузить DLL */ }

            else { /* приложение  имеет право

        пользоваться функциями DLL через hMyDll */ }

      Стандартным расширением файла библиотеки Windows считает .dll, если не указать другое расширение. Если в имени файла  указан и путь, то только он будет  использоваться для поиска файла. В  противном случае Windows будет искать файл по той же схеме, что и в случае неявно подключенных DLL, начиная с каталога, из которого загружается exe-файл, и продолжая в соответствии со значением PATH.

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

      Если  файл обнаружен и библиотека успешно  загрузилась, функция ::LoadLibrary возвращает ее дескриптор, который используется для доступа к функциям библиотеки.

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

         // тип PFN_MyFunction будет объявлять указатель

                   на функцию, 

            // принимающую указатель  на символьный буфер

        и выдающую значение типа int  typedef int

        (WINAPI *PFN_MyFunction)(char *);

            ……  PFN_MyFunction pfnMyFunction;

      Затем следует получить дескриптор библиотеки, при помощи которого и определить адреса функций, например адрес фунции с именем MyFunction:

         hMyDll=::LoadLibrary(“MyDLL”);

            pfnMyFunction=(PFN_MyFunction)::GetProcAddress

                                 (hMyDll,”MyFunction”);

            ……  int iCode=(*pfnMyFunction)(“Hello”);

      Адрес функции определяется при помощи функции ::GetProcAddress, ей следует передать имя библиотеки и имя функции. Последнее должно передаваться в том виде, в котором эксаортируется из DLL.

      Можно также сослаться на функцию по порядковому номеру, по которому она экспортируется (при этом для создания библиотеки должен использоваться def-файл, об этом будет рассказано далее):

         pfnMyFunction=(PFN_MyFunction)::GetProcAddress

      (hMyDll,     MAKEINTRESOURCE(1));

      После завершения работы с библиотекой динамической компоновки, ее можно выгрузить из памяти процесса с помощью функции ::FreeLibrary:

      2.4. Пример неявного  подключения DLL приложением

 

      Приведем  теперь исходный код простого приложения, которое использует функцию 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.

      2.5. Пример динамической  загрузки DLL приложением

 

      Приведем  теперь полностью исходный код простого приложения, которое использует функцию 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=LoadLibrary(“MyDLL”))==NULL) return 1; 

                  PFN_MyFunction pfnMyFunction;

                  pfnMyFunction=(PFN_MyFunction)

                 GetProcAddress(hMyDll,”MyFunction”);

                  int iCode=(*pfnMyFunction)(“Hello”);

                  FreeLibrary(hMyDll);   return 0;  }

      Теперь, познакомившись с принципами работы библиотек DLL в  приложениях, рассмотрим способы их создания. При разработке приложении функции, к которым обращается несколько процессов, желательно размещать в DLL. Это позволяет более рационально использовать память в Windows.

      Проще всего создать новый проект DLL с помощью мастера AppWizard, который  автоматически выполняет многие операции. Для простых DLL, таких как рассмотренные в этой главе, необходимо выбрать тип проекта Win32 Dynamic-Link Library. Новому проекту будут присвоены все необходимые параметры для создания библиотеки DLL. Файлы исходных текстов придется добавлять к проекту вручную.

      Если  же планируется в полной мере использовать функциональные возможности MFC, такие  как документы и представления, или намерены создать сервер автоматизации OLE, лучше выбрать тип проекта MFC AppWizard (dll). В этом случае, помимо присвоения проекту параметров для подключения динамических библиотек, мастер проделает некоторую дополнительную работу.

 

      

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

 

      Задание: Создайте командный файл резервного копирования файлов с определенными расширениями из разных каталогов с возможностью создания резервного каталога, если его нет в системе.

      Ход выполнения работы:

  1. Создаём командный файл с названием kp.bat
  2. Далее с помощью блокнота вписывает в него следующие команды:

      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

  1. Сохраняем изменения и запускаем комадный файл kp.bat 

Заключение

 

      При выполнении этой контрольной работы я узнал что такое Мультипрограммирование и его виды. Его появление привело  к росту эффективности работы процессора а так же позволяет выполнять несколько задач сразу. Узнал что такое DLL файлы, для чего они нужны и способы их загрузки. Так же научился создавать командные файлы резервного копирования файлов.

Информация о работе Мультипрограммирование. Мультипрограммирование в системах разделения времени.. Библиотеки динамической компоновки DLL