Иллюстрированный самоучитель по теории операционных систем

Динамические библиотеки

В Windows и OS/2 используется именно такой способ загрузки. Исполняемый модуль в этих системах содержит ссылки на другие модули, называемые DLL (Dynamically Loadable Library, динамически загружаемая библиотека). Фактически, каждый модуль в этих системах обязан содержать хотя бы одну ссылку на DLL, потому что интерфейс к системным вызовам в этих ОС также реализован в виде DLL.

DLL представляют собой библиотеки в том смысле, что обычно они собираются из нескольких объектных модулей. Но, в отличие от архивных библиотек, из DLL нельзя извлечь отдельный модуль, при присоединении библиотеки к программе она присоединяется и загружается целиком.

Главное достоинство DLL состоит в том, что модуль (как основной, так и библиотечный), по собственному желанию, может выбирать различные библиотеки, подгружая их уже после своей собственной загрузки. При этом нет даже строгого ограничения на совместимость этих библиотек по вызовам (две библиотеки совместимы по вызовам, если они имеют одинаковые точки входа с одинаковой семантикой): загрузчик предоставляет возможность просмотреть список глобальных символов, определенных в библиотеке и получить указатель на каждый символ, обратившись к нему по имени (впрочем, количество и типы параметров или тип переменной, а тем более их семантику, загрузчик не сообщает – эту информацию надо получать из других источников, например из списка зарегистрированных в системе объектов СОМ).

Особенно удобна возможность вызывать любую функцию по имени при обращении к внешним модулям из интерпретируемых языков. В примере 3.9 для подключения внешних библиотек (в данном случае это стандартная библиотека RexxUtil и библиотека доступа к сетевым сервисам rxSock) применяются две процедуры: сначала RxFuncAdd с тремя параметрами: имя символа REXX, который будет использоваться для обращения к вызываемой функции, имя DLL и имя символа в этой DLL, а потом специальная функция, предоставляемая модулем (sysLoadFunc и sockLoadFunc соответственно), которая регистрирует в интерпретаторе REXX остальные функции модуля.

Пример 3.9. Пример использования динамической библиотеки (здесь – REXX || Socket) в интерпретируемом языке:

/ ° ° ° ° ° ° ° ° ° °
ПРОСТОЙ HTTP клиент на REXX
Dmitry Maximovich 2:5030/544.60 aka maxim@pabl.ru
 ° ° ° ° ° ° ° ° ° °/
PARSE VALUE ARC (1) WITH Al A2
IF Al = " THEN DO
SAY 'USAGE: wwwget hostname[/path] [port]' EXIT
END
ELSE
DO
PARSE VALUE Al WITH B1'/'B2
sServer = Bl
IF B2 = '' THEM
DO
sRequest = 'GET / HTTP 1.0'|I"ODOAODOA"x
SAY''Requesting /' END ELSE DO
sRequest = 'GET /'|IB2I|' HTTP 1.0'|I"ODOAODOA"x
SAY 'Requesting /'||B2
END
END
IF A2 <> " THEN
DO
nPortNumber = A2
END
-ELSE
DO
nPortNumber =80
END
/* Загрузить REXX Socket Library если еще не загружена*/
IF RxFuncQuery("SockLoadFuncs") THEN
DO
re = RxFuncAddf"SockLoadFuncs","rxSock","SockLoadFuncs")
re = SockLoadFuncs ()
END
IF RxFuncQuery("SysLoadFuncs") THEN
DO
re = RxFuncAdd("SysLoadFuncs","RexxUtil","SysLoadFuncs") re = SysLoadFuncs()
END
rc=SockGetHostByName(sServer,"host.")
IF rс <> 1 THEN
DO
SAY 'CANNOT RESOLVE HOSTNAME TO ADDRESS: 'sServer EXIT – 1 END
SAY 'Trying server: 'host.name1, address: 'host.addr', port: 'nPortNumber
socket = SockSocket('AF_INET','SOCK_STREAM',0) IF socket < 0 THEN DO
SAY 'UNABLE TO CREATE A SOCKET' EXIT – 1
END
address.familу = 'AF_INET' address.port = nPortNumber address.addr = host.addr
rc = SockConnect(socket,'address.')
IF re < 0 THEN
DO
SAY 'UNABLE TO CONNECT TO SERVER:'address.addr
SIGNAL DO
END
re = SockSend(socket, sRequest)
SAY 'REQUEST' ° ° ° ° ° ° ° ° ° °*'
Resp = ''
DO FOREVER
re = SockRecv(socket,"sReceive",256)
IF re <= 0 THEN LEAVE
Resp = Resp || sReceive END
SAY
/* CR › CRLF */
nStart = 1
nStop = pos(X2C("OA"), Resp)
do while nStop > 0
SAY SUBSTR(Resp,nStart,nStop-nStart)
nStart = nStop + 1
nStop = pos(X2C("OA"), Resp, nStart)
end
DO:
rc = SockShutDown(socket,2)
rc = SockClose(socket)
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.