Работа с динамической библиотекой подпрограмм, находящейся в памяти



Иногда, желательно чтобы программа состояла только из одного исполняемого файла.
А что делать, если для работы программы нужны другие файлы, например, динамические библиотеки подпрограмм (DLLки)?
Если их немного и они имеют небольшой размер, то вполне реально разместить их в теле исполняемого файла.

Для примера используем программу, требующую для своей работы файл inpout32.dll. Это драйвер доступа к портам компа.
Программа определяет текущую температуру процессора и системной платы, а также текущую загрузку процессора.

Код программы
Код:
#ADR_REG = $295 ;Это адреса регистров системной платы, с помощью которых можно узнать температуру
#DATA_REG = $296

*HModule=LoadLibraryM(?DLL) ; Загрузка динамической библиотеки из тела исполняемого файла
*Inp32_address=GetProcAddressM(*HModule, "Inp32") ; Узнаём адрес функции "Inp32" DLLки
*Out32_address=GetProcAddressM(*HModule, "Out32") ; Узнаём адрес функции "Out32" DLLки

Procedure Termo(z) ; Эта процедура работает в параллельном потоке
Shared *Inp32_address, *Out32_address

Repeat ; Начало "безконечного" цикла Repeat ForEver
CallFunctionFast(*Out32_address, #ADR_REG, $2B) ; Получает текущую температуру процессора
x=CallFunctionFast(*Inp32_address, #DATA_REG)
SetGadgetItemText(0,0,StrU(x, #PB_Byte)+" °C",1) ; отображаем её в таблице

CallFunctionFast(*Out32_address, #ADR_REG, $29) ; Получает текущую температуру системной платы
x=CallFunctionFast(*Inp32_address, #DATA_REG)
SetGadgetItemText(0,1,StrU(x, #PB_Byte)+" °C",1) ; отображаем её в таблице

SetGadgetText(3, Str(CpuUsage())+" %" ) ; Получаем и отображаем текущую загрузку процессора

Delay(1000) ; Пауза, равная 1 секунде.

ForEver
EndProcedure

OpenWindow(0,0,0,274,100,"TermoControl",#PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered)

ListIconGadget(0,2,2,270,70,"Имя",120,#PB_ListIcon_GridLines) ; Таблица
SetGadgetFont(0,LoadFont(0,"MS Sans Serif",10) ) ; Шрифт используемый в таблице
AddGadgetColumn(0, 1, "Температура", 140) ; Добавление колонки в таблицу
AddGadgetItem(0, 0, "Процессор") ; Добавление строк в таблицу
AddGadgetItem(0, 1, "Мат. плата")

TextGadget(2,10, 80,140,16,"Процессор загружен на ")
TextGadget(3,150, 80,50,16,"") ; Здесь будет отображаться текущая загрузка процессора

CreateThread(@Termo(), 0) ; Запуск кода процедуры "Termo" в параллельном потоке

HideWindow(0,0) ; Отображение окна

Repeat ; Главный цикл программы
Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow

FreeLibraryM(*HModule) ; При завершении работы проги, выгружаем DLLку из памяти
End

DataSection ; Добавление файла inpout32.dll в секцию кода, исполняемого файла
DLL:
IncludeBinary "inpout32.dll"
EndDataSection
Для компиляции программы нужна специальная библиотека с дополнительными функциями для PureBasic, именуемая PBOSL Найти её можно здесь

В начале программы, в константы #ADR_REG и #DATA_REG записываются адреса регистров, из которых можно прочитать текущие температуры.
Далее с помощью функции LoadLibraryM из библиотеки PBOSL регистрируем DLLку, находящуюся в теле исполняемого файла и получаем её начальный адрес в памяти. Потом с помощью функции GetProcAddressM определяем адреса функций DLLки - "Inp32" и "Out32".
Зная эти адреса, можно без проблем работать с функциями DLLки


В процедуре Termo производится периодическое считывание температуры и отображение её в таблице. Код данной процедуры выполняется в параллельном потоке и можно так сказать, "живёт" сам по себе.



Вот скрин проги.
скриншот


PS.
Этот метод определения температуры работает только при условии что в компе интеловский процессор и системная плата поддерживает данную функцию.


Архив с программой TermoControl и её исходным текстом, можно скачать здесь



Учебник                Главная
Сайт создан в системе uCoz