Создание и использование DLL (Microsoft Visual C++)

Error404

Пользователь
Регистрация
16.11.04
Сообщения
929
Реакции
0
Баллы
16
Введение

Создать DLL намного легче, чем вы думаете. Библиотеки DLL очень полезны, если вы программируете под Windows. В этих библиотеках обычно хранят часто используемые подпрограммы. В статье рассказывается как создать простую DLL и показано, как вызвать функции, содержащиеся в ней. Примеры расчитаны на использование Microsoft Visual C++ 6.0, но нетрудно перевести их на любой диалект C++.
Создание 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 (т.е. ее можно вызывать из нашей программы).
После компиляции мы получим библиотеку. Теперь посммотрим, как ее можно использовать.

Использование DLL (с библиотекой импорта)

Сначала посмотрим, как использовать DLL вместе с библиотекой импорта (dlltest.lib), которая получается при компиляции предыдущего примера. Этот метод очень прост, так как в таком случае нужно просто включить заголовочный файл библиотеки и саму библиотеку в проект. Пример:
Исходный файл приложения, использующего библиотеку DLL (DLLRUN01.EXE)
Код:
#include <conio.h>
#include <dlltest.h>
void main()
{ NumberList(); LetterList(); getch();[CENTER]}[/CENTER]




Это будет прекрасно работать, если у вас есть заголовочный файл и библиотека импорта (dlltest.lib) находится в каталоге, прописанном в библиотечных путях. Перед запуском приложения, убедитесь, что DLL находится в каталоге, прописанном в системной переменной PATH или в том же каталоге, что и исполняемый файл, иначе вы получите сообщение об ошибке. Однако если 10 программ используют эту DLL, вам нужна всего одна ее копия, лежащая, например, в каталоге Windows\System.
Результаты работы DLLRUN01.EXE
Код:
This function was called from C:\DLLTEST\DLLRUN01.EXE
NumberList(): 0 1 2 3 4 5 6 7 8 9
This function was called from C:\DLLTEST\DLLRUN01.EXE
LetterList(): a b c d e f g h i j k l m n o p q r s t u v w x y z

Использование DLL без библиотеки импорта

Теперь посмотрим, как загрузить DLL "на лету". Это нужно в случае, если не вы разрабатывали эту DLL и у вас нет заголовочного файла и библиотеки импорта.
Исходный файл приложения, использующего библиотеку DLL - консольное приложение Win32 (DLLRUN01.EXE)


Код:
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#define MAXMODULE 50
typedef void (WINAPI*cfunc)();
cfunc NumberList;
cfunc LetterList;
void main()
{ HINSTANCE hLib=LoadLibrary("DLLTEST.DLL"); if(hLib==NULL) { cout << "Unable to load library!" << endl; getch(); return; } char mod[MAXMODULE]; GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, MAXMODULE); cout << "Library loaded: " << mod << endl; NumberList=(cfunc)GetProcAddress((HMODULE)hLib, "NumberList"); LetterList=(cfunc)GetProcAddress((HMODULE)hLib, "LetterList"); if((NumberList==NULL) || (LetterList==NULL)) { cout << "Unable to load function(s)." << endl; FreeLibrary((HMODULE)hLib); return; } NumberList(); LetterList(); FreeLibrary((HMODULE)hLib); getch();
}

Этот код загружает DLL (если она находится в путях или в текущем каталоге), а затем определяет адреса функций, которые мы будем вызывать. Конечно, в этом случае пришлось написать намного больше кода, и, соответственно, придется отловить немало ошибок. Однако такой подход универсальней.
Результаты работы DLLRUN02.EXE


Код:
[/B][/FONT][/COLOR]Library loaded: C:\DLLTEST\DLLTEST.DLL
This function was called from C:\DLLTEST\DLLRUN02.EXE
NumberList(): 0 1 2 3 4 5 6 7 8 9
This function was called from C:\DLLTEST\DLLRUN02.EXE
LetterList(): a b c d e f g h i j k l m n o p q r s t u v w x y z[COLOR=#ffd700][FONT=Tahoma][B]
 

Статистика форума

Темы
205.158
Сообщения
386.381
Пользователи
327.906
Новый пользователь
ника678
Сверху Снизу