Использование NuMega DriverStudio для написания WDM-драйверов | страница 41



>EXPORT int GetMemSize(void) {

> CHAR bufInput[4]; // Это пустой входной буфер, который будет

>  //передан устройсву

> unsigned long bufOutput; //Буфер, куда драйвер запишет результат.

> ULONG nOutput; //Длина возвращенных драйвером данных, байт

>  // Вызвать функцию device IO Control с кодом XDSPDRV_IOCTL_GETMEMSIZE

> if (!DeviceIoControl(hDevice, XDSPDRV_IOCTL_GETMEMSIZE, bufInput, 4, &bufOutput, 4, &nOutput, NULL)) return(0); //Неудача

> else return(bufOutput); //Кол-во памяти

>}

Таким образом, наша библиотека экпортирует всего четыре функции для работы с устройством. Все они имеют простой синтаксис и просты в использовании. Использование dll в нашем случае позволяет программисту не думать о сложных системных вызовах, необходимых для общения с драйвером, о формате передаваемых ему данных, а сосредоточится на решении прикладных задач.

2.5 Подключение dll-библиотеки к приложению.

После того, как написан драйвер и dll-библиотека для работы с ним, пришло время написать приложение пользоваеля, работающее с устройством. Оно будет взаимодействовать с драйвером через dll-библиотеку. Естественно, написано оно также будет в среде Visual C++. В принципе, его можно было бы реализовать в среде Visual Basic, Delphi или CВuilder, но это приведет к некоторым трудностям, прежде всего в использовании системных вызовов и структур данных. В данном разделе, в отличие от предыдущих, не рассматривается какое-либо конкретное приложение, а даются общие рекомендации по написанию такой программы.

Подключение библиотеки к приложению не требует особых усилий. Библиотека подключается при помощи системного вызова HMODULE LoadLibrary(char* LibraryName), где LibraryName — строка с именем файла dll-библиотеки. Возвращаемое значение — хендл (дескриптор) бибилиотеки. Если функция возвратила NULL, то произошла ошибка при подключении библиотеки.

После подключения библиотеки можно из нее импортировать функции. Импорт функции производится при помощи системного вызова

>FARPROC GetProcAdress(HMODULE hModule, char * ProcName)

• hModule — хэндл библиотеки, возвращенный LoadLibrary;

• ProcName — строка с именем импортируемой функции. Вызов GetProcAdress возвращает адрес функции с заданным именем и NULL, если такой функции нет в библиотеке.

Так как из библиотеки импортируется не само тело функции, а ее адрес, то вызов такой функции превращается в непростое дело. Прежде всего, в программе объявляется не сама функция, а переменная, содержащая указатель на нее. Естественно, работа с таким указателем сильно отличается от работы с указателем на число или строку. Ведь функция в отличие от просто переменной возвращает значение и принимает некоторые параметры, поэтому указатель на нее должен быть объявлен специальным образом.