On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru






 

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

Введение

Создать 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();
}

Это будет прекрасно работать, если у вас есть заголовочный файл и библиотека импорта (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

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



Литература по Microsoft Visual C++