Явный вызов функций DLL

Явный вызов функций DLL несколько утомителен, зато дает Вашей программе настоящий полный контроль за работой DLL. Вы можете спокойно определить есть ли DLL и вообще есть ли в ней соответствующая функция. Давайте посмотрим как это делается. Сначала нам надо получить указатель на DLL - это делает функция LoadLibrary():

HMODULE LoadLibrary
(
LPCTSTR lpLibFileName // имя модуля
);

Она может завершиться как успешно, так и нет. Если успешно, то вернет указатель на DLL. Что она сделает ? Она поищет DLL. Еcли найдет, то загрузит ее в память и вернет Вам указатель. Так как DLL загружается в память Вы не можете просто так ее бросить, Вам надо ее выгрузить, а для этого есть функция FreeLibrary(), которая как раз сообщит Windows, что данная программа DLL больше не использует. Вообще за загрузку и выгрузку DLL отвечает Windows, так как DLL может использоваться несколькими программами. Вы просто говорите, что программа начинает использовать DLL (LoadLibrary) и заканчивает (FreeLibrary), а OC сама разбирается надо грузить ее в память или наоборот убирать, так как никто не использует ее. Вот пример:

// TestDLL.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
HINSTANCE hModule=NULL;
hModule=::LoadLibrary("user32.dll");
if (hModule!=NULL)
{
::FreeLibrary(hModule);
}
else cout << "error load Dll" << endl;
}

Как только мы получили указатель на DLL мы можем получить адрес функции по имени функции. Естественно нам имя нужно знать. Сначала надо объявить прототип функции typedef BOOL (WINAPI MESS)(UINT);. Обратите внимание, что я явно указал тип вызова WINAPI, что означает _stdcall так как С++ использует _cdecl, который не совместим с WIN32 API. Объявив прототип я могу создать указатель на функцию, а потом воспользовавшись GetProcAddress() получить функцию и уже ее вызывать.

// TestDLL.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
HINSTANCE hModule=NULL;
typedef BOOL (WINAPI MESS)(UINT);
MESS* me=NULL;
hModule=::LoadLibrary("user32.dll");
if (hModule!=NULL)
{
me=(MESS*)::GetProcAddress((HMODULE)hModule,"MessageBeep");
if (me!=NULL)
{
UINT type=1;
BOOL result;
result=(*me)(type);
}
else cout << "Error Load function" << endl;
::FreeLibrary(hModule);
}
else cout << "error load Dll" << endl;

Внимание !!! Тщательно следите на типом вызова функций. Win32 пользуется методом вызова функций PASCAL - _stdcall, а VC методом вызова C, а в Windows стандарт вызова функций PASCAL. Разница этих методов в помещении параметров в стек. Будет время напишу подробнее. Просто помните об этом. Свои DLL Вы можете вызывать без WINAPI, а вот чужие надо знать, если стандартный API, то WINAPI, иначе надо выяснять. Как ?? Просто получаете ошибку вызова, если ошибетесь :-)