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

Автор : Пётр Высочанский

# Вернуться на главную

Иногда, желательно чтобы программа состояла только из одного исполняемого файла.
А что делать, если для работы программы нужны другие файлы, например, динамические библиотеки подпрограмм (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 

#flag= #PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered
 OpenWindow(0,0,0,274,100,"TermoControl",#flag)
 
   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 и её исходным текстом, можно скачать здесь

#
 
Материал взят с сайта : http://pure-basic.narod.ru/docs/dll_mem.html

Вернуться на главную

#










Используются технологии uCoz