Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба6.doc
Скачиваний:
6
Добавлен:
12.11.2019
Размер:
82.94 Кб
Скачать

2. Dll и адресное пространство процесса

Зачастую создать DLL проще, чем приложение, потому что она является лишь набором автономных функций, пригодных для использования любой программой, причем в DLL обычно нет кода, предназначенного для обработки циклов выборки сообщений или создания окон DLL представляет собой набор модулей исходного кода, в каждом из которых содержится определенное число функций, вызываемых приложением (исполняемым файлом) или другими DLL. Файлы с исходным кодом компилируются и компонуются так же, как и при создании ЕХЕ-файла. Но, создавая DLL, необходимо указывать компоновщику ключ /DLL. Тогда компоновщик записывает в конечный файл информацию, по которой загрузчик операционной системы определяет, что данный файл — DLL, а не приложение.

Чтобы приложение (или другая DLL) могло вызывать функции, содержащиеся в DLL, образ ее файла нужно сначала спроецировать на адресное пространство вызывающего процесса. Это достигается либо за счет неявного связывания при загрузке, либо за счет явного — в период выполнения.

Как только DLL спроецирована на адресное пространство вызывающего процесса, ее функции доступны всем потокам этого процесса. Фактически библиотеки при этом теряют почти всю индивидуальность: для потоков код и данные DLL — просто дополнительные код и данные, оказавшиеся в адресном пространстве процесса. Когда поток вызывает из DLL какую-то функцию, та считывает свои параметры из стека потока и размещает в этом стеке собственные локальные переменные. Кроме того, любые созданные кодом DLL объекты принадлежат вызывающему потоку или процессу — DLL ничем не владеет,

Например, если DLL-функция вызывает VirtualAlloc, резервируется регион в адресном пространстве того процесса, которому принадлежит поток, обратившийся к DLL функции. Если DLL будет выгружена из адресного пространства процесса, зарезервированный регион не освободится, так как система не фиксирует того, что регион зарезервирован DLL-функцисй. Считается, что он принадлежит процессу и поэтому освободится, только если поток этого процесса вызовет VirtualFree или завершится сам процесс.

Библиотеки DLL очень полезны, если вы программируете под Windows. В этих библиотеках обычно хранят часто используемые подпрограммы. Далее рассказывается, как создать простую DLL и показано, как вызвать функции, содержащиеся в ней. Примеры рассчитаны на использование Microsoft Visual C++ 6.0, но нетрудно перевести их на любой диалект C++.

2.Создание dll

Ничего особенного здесь нет. Как обычно, вы просто пишите функции, как в обычной программе. Если вы используете MSVC, создайте новый проект и укажите, что вы создаете Win32 Dynamic-Link Library. После компиляции вы получите DLL, библиотеку импорта (.lib) и библиотеку экспорта (.exp). Далее показан примерный код DLL:

Заголовочный файл (DLLTEST.H)

#ifndef _DLLTEST_H_ #define _DLLTEST_H_ #include <iostream.h> #include <stdio.h> #include <windows.h> extern "C" __declspec(dllexport) void NumberList(); extern "C" __declspec(dllexport) void LetterList(); #endif

Код библиотеки (DLLTEST.CPP)

#include "dlltest.h"

#define MAXMODULE 50

char module[MAXMODULE];

extern "C" __declspec(dllexport) void NumberList() {     GetModuleFileName(NULL, (LPTSTR)module, MAXMODULE);     cout << "\n\nThis function was called from "     << module     << endl << endl;     cout << "NumberList(): ";     for(int i=0; i<10; i++)     {        cout << i << " ";     }     cout << endl << endl; }

extern "C" __declspec(dllexport) void LetterList() {     GetModuleFileName(NULL, (LPTSTR)module, MAXMODULE);     cout << "\n\nThis function was called from "     << module     << endl << endl;     cout << "LetterList(): ";     for(int i=0; i<26; i++)     {        cout << char(97 + i) << " ";     }     cout << endl << endl; }

Как видите, ничего особенного в коде нет. Приложение, используемое для примера - консольное, так что здесь просто запрограммированы две функции, выводящие текст. Строка extern "C" __declspec(dllexport) означает, что функция будет видна вне DLL (т.е. ее можно вызывать из нашей программы). После компиляции мы получим библиотеку. Теперь посмотрим, как ее можно использовать.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]