Monday, July 20, 2009

Импорт и экспорт функций DLL

В MS Visual Studio экспортировать функции можно перечислением их имён в DEF файле, либо добавлением в коде к объявлениям функций ключевого слова __declspec(dllexport).
На эту тему можно почитать в MSDN в разделе Импортирование и Экспортирование.
Для того, чтобы подключить и использовать функции DLL из другого исполняемого приложения, нужно объявить функцию со спецификатором __declspec(dllexport)

__declspec(dllexport) void func();
__declspec(dllexport) int i;

Вообще говоря, экспортировать можно не только функции, но и переменные. Причём для использования импортируемых функций указывать __declspec(dllimport) не обязательно, а для переменных это необходимо.

__declspec(dllimport) void func(); //Необязательно использовать спецификатор импорта
__declspec(dllimport) int i;

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

#ifdef _DLLAPI_
#define DLLAPI __declspec( dllexport )
#else
#define DLLAPI __declspec( dllimport )
#endif

Этот заголовочный файл подключается к модулям DLL и внешнего приложения, использующего эту DLL. Например:
В файле MyDllApi.h определяем макрос:

// Файл MyDllApi.h
#pragma once
#ifdef _DLLAPI_
#define DLLAPI __declspec( dllexport )
#else
#define DLLAPI __declspec( dllimport )
#endif

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

// Файл MyModule.h
#include "MyDllApi.h"

int DLLAPI intFunc();
void DLLAPI voidFunc(int param);

В cpp файле модуля пишем реализацию функций. Здесь для простоты они будут пустыми:

// Файл MyModule.cpp
#include "MyModule.h"

int intFunc()
{
return 1;
}

void voidFunc(int param)
{
return;
}

Теперь в приложении, использующем библиотеку, просто подключаем заголовочный файл MyModule.h и можно использовать экспортируемые из библиотеки функции.
Явно подключить библиотеку (LIB-файл) для Visual Studio можно прямо в коде без редактирования настроек проекта. Для этого в файл MyDllApi.h нужно добавить следующий макрос:

#ifndef _NOAUTOLIB_
#ifdef _DEBUG
#pragma comment(lib, "mydll.lib")
#else
#pragma comment(lib, "mydll.lib")
#endif
#endif

Пользуясь этим же подходом можно экспортировать/импортировать классы. Объявление экспортируемого класса будет выглядеть так:

class DLLAPI MyClass
{
...
}

Рекомендую также почитать статью по теме на RSDN: Использование DLL в программе на Visual C++

2 comments:

Anonymous said...

Очень интересная статья получилась! Респект автору! :)

Anonymous said...

Какая познавательная статья вышла! Респект автору! :)