Неявное подключение и использование динамических библиотек (dll)

Для того, чтобы можно было пользоваться функциями расположенными в динамической библиотеке их нужно объявлять с ключевым словом __declspec(dllexport), например: void __declspec(dllexport) MyFunc(), а вот в проекте, к которому будет подключен dll файл, следует, придерживаться данному правилу объявления импортируемых функций: void __declspec(dllimport) MyFunc(). Для наглядности я опишу процесс создания библиотеки dll и её использования.
В качестве примера запихаем в dll функцию сложения двух чисел. Для начала объявим прототип функции сложения в заголовочном файле header.h:

int __declspec(dllexport) Sum(int a, int b);

И реализуем в файле DllMain.cpp:

#include <windows.h>
#include "header.h"

bool APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	return true;
}

int __declspec(dllexport) Sum(int a, int b)
{
	return a + b;
}


После построения проекта на выходе у нас будет 2 файла: DllExport.dll и DllExport.lib. Все бы хорошо, но можно сделать одну удобную фишку! При использовании данной библиотеки в других проектах нам придется заново объявлять прототипы нужных функций, но ведь у нас есть заголовочный файл header.h, благодаря которому можно будет забить на объявление прототипов, но придется его немного поправить, т.к. при компиляции проекта использующего dll библиотеку нам нужно использовать ключевое слово __declspec(dllimport), а при компиляции в dll проекте нужно использовать __declspec(dllexport). Для решения данной проблемы будем использовать условную директиву компилятора: ifdef.
DllMain.cpp:

#define COMPILE_DLL
#include <windows.h>
#include "header.h"

bool APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	return true;
}

int __declspec(dllexport) Sum(int a, int b)
{
	return a + b;
}

header.h:

#ifdef COMPILE_DLL
int __declspec(dllexport) Sum(int a, int b);
#else
int __declspec(dllimport) Sum(int a, int b);
#endif

Теперь при компиляции header.h, компилятор будет выбирать нужный вариант объявления прототипа функции. Теперь я напишу пример программы использующей нашу библиотеку:
DllImport.cpp:

#include <Windows.h>
#include <iostream>
#include "header.h"

#pragma comment(lib, "DllExport.lib")

int main(int argc, char* argv[])
{
	int a, b;

	std::cout << "Set a= ";
	std::cin >> a;
	std::cout << "Set b= ";
	std::cin >> b;
	std::cout << "Sum = " << Sum(a, b) << std::endl;

	system("pause");
	return 0;
}

Команда #pragma comment(lib, «DllExport.lib») как раз и осуществляет неявное подключение нашей dll.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s