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