Для того, чтобы можно было пользоваться функциями расположенными в динамической библиотеке их нужно объявлять с ключевым словом __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.