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

  • Автор темы Error404
  • 405
  • Обновлено
  • 22, Jun 2013
  • #1


Создать DLL намного легче, чем вы думаете.

Библиотеки DLL очень полезны, если вы программируете под Windows.

В этих библиотеках обычно хранят часто используемые подпрограммы.

В статье рассказывается как создать простую DLL и показано, как вызвать функции, содержащиеся в ней.

Примеры расчитаны на использование Microsoft Visual C++ 6.0, но нетрудно перевести их на любой диалект C++.

Ничего особенного здесь нет.

Как обычно, вы просто пишите функции, как в обычной программе.

Если вы используете 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 вместе с библиотекой импорта (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 - консольное приложение 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]


Error404


Рег
16 Nov, 2004

Тем
563

Постов
803

Баллов
6433
Тем
49554
Комментарии
57426
Опыт
552966