Что такое Windows API. Введение в Win32 API

Введение

Последние 10 лет Windows – самая популярная (91,02% ) операционная система на рынке персональных компьютеров. Операционные системы Windows работают на платформах x86, AMD64, IA-64. Существовали также версии для DEC Alpha, MIPSи PowerPC.

Семейство Windows NT:

Операционные системы этого семейства работали на процессорах с архитектурой IA-32 и некоторых RISC-процессорах: Alpha, MIPS, Power PC (до версии 2000, которая вышла только в версии для IA-32). Windows NT являются полностью 32-битными операционными системами, и, в отличие от версий 1.0–3.x и 9x, не нуждаются в поддержке со стороны MS-DOS.

Windows NT 3.1 (1993)

Windows NT 3.5 (1994)

Windows NT 3.51 (1995)

Windows NT 4.0 (1996)

Windows 2000 (2000) – Windows NT 5.0

Windows XP (2001) – Windows NT 5.1

Windows XP 64-bit Edition (2006) – Windows NT 5.2

Windows Server 2003 (2003) – Windows NT 5.2

Windows Vista (2006) – Windows NT 6.0

Windows Home Server (2007)

Windows Server 2008

Windows 7 (2009) – Windows NT 7.0 (Актуальная версия – 6.1)

В основу семейства Windows NT положено разделение адресных пространств между процессами. Каждый процесс имеет возможность работать с выделенной ему памятью. Однако он не имеет прав для записи в память других процессов, драйверов и системного кода.

Семейство Windows NT относится к операционным системам с вытесняющей многозадачностью, а не к операционным системам реального времени. Разделение процессорного времени между потоками происходит по принципу «карусели». Ядро операционной системы выделяет квант времени (в Windows 2000 квант равен примерно 20 мс) каждому из потоков по очереди при условии, что все потоки имеют одинаковый приоритет. Поток может отказаться от выделенного ему кванта времени. В этом случае, система перехватывает у него управление (даже если выделенный квант времени не закончен) и передаёт управление другому потоку. При передаче управления другому потоку система сохраняет состояние всех регистров процессора в особой структуре в оперативной памяти. Эта структура называется контекстом потока. Сохранение контекста потока достаточно для последующего возобновления его работы.

API (Application Programming Interface – интерфейс прикладных программ) – это множество функций, организованных, обычно, в виде DLL. Функции API позволяют организовать интерфейс между прикладной программой и средой, в которой работает эта программа. Вызов функций API позволяет программе получать доступ к ресурсам среды и управлять ее работой. Как правило, API задает стандарт взаимодействия среды и прикладной программы.

Win32 – это название интерфейса, ориентированного на 32-х разрядные приложения и реализованного на таких известных платформах как Windows 95, Windows 98, Windows NT, Windows CE. Функции, составляющие этот интерфейс, позволяют прикладной программе получать доступ к ресурсам операционной системы и управлять ее работой. Более ранние версии Windows используют интерфейс, известный как Win16. Конечно, не все функции, составляющие интерфейс Win32, реализованы в полной мере на всех платформах, так что вызов одной и той же функции под NT приведет к определенному результату, а под Windows 95 работает как вызов заглушки. Любое из приложений, работающее в среде Windows, прямо или косвенно вызывает функции, входящие в Win32 API.

Функции, составляющие Win32 интерфейс, организованы в виде нескольких динамически подключаемых библиотек (DLL) и исполняемых файлов.

API функции не обязательно входят в состав Win32 интерфейса. Например, MAPI интерфейс (Messaging Application Programming Interface) составляют функции, предназначенные для обработки сообщений электронной почты, TAPI (Telephone API) – функции работы с телефонными сообщениями. MAPI, TAPI, также как и Win32 это некоторый набор функций, задающий определенный стандарт взаимодействия

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


1. Теоретическая часть

1.1 Возможности Win32 для нахождения списка запущенных процессов

программа алгоритм библиотека пользователь

Win32 предоставляет несколько способов перечисления запущенных процессов. К сожалению, нет единого способа, который бы работал на всех Win32-платформах. Программистам приходится комбинировать несколько методов в одной программе, чтобы она работала на всех версиях Windows.

1. Рассмотрим следующие методы:

2. С помощью библиотеки Process Status Helper (PSAPI)

3. С помощью ToolHelp32 API

4. С помощью недокументированной функции ZwQuerySystemInformation

5. Через счетчики производительности

6. С использованием интерфейсов Windows Management Instrumentation

7. Функции интерфейса сокетов

1.2 Использование библиотеки Process Status Helper

Библиотека Process Status Helper, известная также под названием PSAPI, предоставляет набор функций, позволяющих получить информацию о процессах и драйверах устройств. Библиотека поставляется в составе Windows 2000/XP и доступна в качестве устанавливаемой компоненты для Windows NT 4.0.

Для перечисления процессов библиотека предоставляет функцию EnumProcesses, которая возвращает массив идентификаторов запущенных процессов. Ниже приведен текст функции EnumProcesses_PsApi, реализующей перечисление процессов с помощью PSAPI.

Функция EnumProcesses не позволяет узнать, сколько места нужно для того, чтобы принять весь массив идентификаторов. Поэтому мы вызываем ее в цикле, увеличивая размер буфера, до тех пор, пока размер возвращенного массива не будет меньше размера буфера.

Поскольку мы хотим помимо идентификаторов процессов получить и имена процессов, мы должны проделать дополнительную работу. Для каждого процесса мы сначала получаем его описатель (handle) c помощью функции OpenProcess и затем используем функцию ЕnumProcessModules, которая возвращает список модулей, загруженных в адресное пространство процесса. Первым модулем в списке всегда является модуль, соответсвующий EXE-файлу программы. Наконец, мы вызываем функцию GetModuleFileNameEx (которая также является частью PSAPI), чтобы получить путь к EXE-файлу по описателю модуля. Мы используем имя EXE-файла без пути в качестве имени процесса.

Нужно обратить внимание на специальную обработку для двух процессов. Мы вынуждены обрабатывать отдельно процесс бездействия системы (Idle) с идентификатором 0, и системный процесс (System), который имеет идентификатор 2 на Windows NT 4 и 8 – на Windows 2000/XP, потому что OpenProcess не позволяет открыть описатель для этих процессов, возвращая код ошибки ERROR_ACCESS_DENIED.



RTOS складається з ядра, планувальника процесів (process manager) і розширених сервісів на рівні користувача. Як справжня мікроядерного операційна система, QNX Neutrino RTOS реалізує в ядрі ОС тільки найбільш фундаментальні сервіси, такі як передача повідомлень, сигнали, таймери, планування потоків, об"єкти синхронізації. Всі інші сервіси ОС, драйвери та програми виконуються як окремі процеси, які ...

Обеспечения является адекватной решению поставленной в техническом задании задачи. 4. ПРОГРАММНАЯ РЕАЛИЗАЦИЯ ПОСТАВЛЕННОЙ ЗАДАЧИ Программная реализация разработанной выше структуры приложения состоит в разработке исполняемого Win32-приложения в среде визуального программирования MS Visual Studio. Проект программного обеспечения состоит из трех классов – CFuzzyApp, CFuzzyDlg, CFuzzy_. В...

Выдачей и приёмом лицензий). В условиях крупных сетей рекомендуется выделение под сервер лицензий отдельного компьютера (или нескольких - для резервирования). 1.1 Архитектура терминальных устройств В компьютерных технологиях трёхуровневая архитектура, синоним трёхзвенная архитектура (по англ. three-tier или Multitier architecture) предполагает наличие следующих компонентов приложения: ...

Доступ, то собственник сервера не идет в милицию, а нанимает хакера и «залатывает брешь» в защите. ГЛАВА 2. УГОЛОВНО-ПРАВОВАЯ ХАРАКТЕРИСТИКА ПРЕСТУПЛЕНИЙ В СФЕРЕ КОМПЬЮТЕРНОЙ ИНФОРМАЦИИ 2.1. Неправомерный доступ к компьютерной информации В статье 272 Уголовного кодекса РФ предусмотрена ответственность за неправомерный доступ к компьютерной информации, охраняемой законом, т.е. информации на...

Реализация Win32 интерфейса (API) в среде ОС реального времени стандарта POSIX


Перевод: А. Николаев
С. Ющенко

Dan Hildebrand
Senior Architect, R&D
QNX Software Systems Ltd.

Введение

Широкое распространение Windows 95 и Windows NT создало спрос на встраиваемые операционные системы реального времени, которые могут приспосабливать для себя исходный код, написанный для Win32 API. В настоящее время, в ответ на это, несколько производителей разрабатывают продукты, которые “грубо” представляют возможности реального времени в Windows NT. К сожалению, Microsoft без особой охоты дает доступ к исходным кодам Windows NT, и, как следствие, эти расширения реального времени выполняются вне операционной системы. Одна из таких реализаций заключается во внедрении “расширений реального времени” непосредственно в слой, отделяющий NT от аппаратной части (NT hardware abstraction layer ) или HAL. Другое дополнение запускает NT как задачу под управлением ОС реального времени, наравне с другими процессами, работающими как отдельные задачи. Оба расширения требуют внесения модификаций в HAL, причем, первое в большей степени, чем второе.

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

Реальное время выполненное внутри HAL

HAL - это нижний уровень программного обеспечения, который соединяет Windows NT с аппаратной частью. Он обеспечивает функции связи с аппаратным обеспечением, такие как прерывания, видео, дисководы и т. д. Модифицируя HAL можно добавить код, который перехватывает прерывание таймера и запускается, в некоторой степени, в реальном масштабе времени.

Так как аппаратные прерывания, в первую очередь, обрабатываются HAL’ом и затем передаются операционной системе, HAL имеет преимущество «первой руки» по отношению к ОС. Вместо того чтобы немедленно передать прерывание, HAL может решить использовать его для управления диспетчером внутри ядра реального времени. В ответ на это, диспетчер может запустить набор резидентных HAL задач в реальном масштабе времени. Так как прерывания не были перехвачены ядром реального времени, они могут быть переданы NT для дальнейшей обработки, и приложения NT могут запускаться в соответствии с тактами CPU, которые больше не заняты задачами реального времени, работающими внутри HAL.

Проблема заключается в том, что эта работа в реальном масштабе времени “невидима” для остальной системы (кроме потерянных на работу ядра реального времени тактов CPU и задач, работающих внутри ядра). А именно, HAL-резидентные задачи реального времени не могут получить прямой доступ к полному сервису, предоставляемому Windows NT (графический интерфейс, дисковые накопители, сеть и т.д.). В результате, разработчики, которые взялись за этот метод, должны найти возможность обеспечения взаимодействия HAL-резидентных задач с приложениями NT, которые могут иметь полный доступ ко всему сервису:

Достоинства и недостатки

При использовании метода, базирующегося на HAL, среда Windows NT модифицируется всего лишь слегка, и это означает для ОС совместимость с драйверами устройств и другими расширениями. Но этот вариант имеет несколько недостатков:

Нет совместимости между стандартной средой и средой реального времени

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

Нестандартная среда разработки

    В связи с различием в структуре и коде приложений, инструменты разработки и отладки приложений реального времени тоже будут отличаться от инструментов для создания обычных приложений. Требуется определенная тренировка перед началом разработки задач реального времени.

Нестабильность

    То, что задачи реального времени работающие в HAL весьма нестабильны в работе, принимается как должное. В то время как среда NT обеспечивает MMU защиту для стандартных задач, ошибки в коде HAL-резидентных приложений реального времени могут легко привести к полному краху NT (“Голубой Экран”). И как результат, среда разработки является довольно хрупкой. Кроме того, приложения реального времени, работающие в HAL, не могут противостоять глобальным сбоям самого NT.

Дополнительные накладные расходы

    Реализация HAL, описанная в прессе, для обработки прерываний в реальном масштабе времени использует метод “опроса прерывания”, который работает на высокой, постоянной частоте (20,000 Hz). Это прерывание с фиксированной частотой, вызывает дополнительные накладные расходы на диспетчеризацию всей системы, обрабатывая прерывание тогда, когда не требуется никакой работы в реальном масштабе времени. Также, увеличивается время ожидания начала работы, так как события реального времени не могут быть обработаны до следующего интервала опроса. Настоящее ядро реального времени управляется событиями, немедленно отвечая на прерывания в момент их возникновения.

Большие требования к памяти

    Использование расширения HAL только добавляет и без того большие требования NT к памяти. В результате, это решение остается неудовлетворительным для многих систем реального времени с ограниченными ресурсами памяти, которые могли бы извлечь пользу из интерфейса Win32.

Реализация реального времени вне Windows NT

Второй вариант добавления возможностей реального времени в Windows NT - это запуск NT как задачи с самым низким приоритетом под управлением ОС реального времени. Так как остальные задачи могут работать с более высоким приоритетом, чем NT, они могут приостановить выполнение NT и достигнуть лучшего детерминизма реального времени. Для большей надежности, эти задачи работают в адресном пространстве отдельном от NT:

К сожалению, этот метод разделяет многие из основных недостатков метода HAL-расширения, описанного выше. Разработчик должен, как и раньше, работать с двумя абсолютно различными интерфейсами и выбирать между ними, в зависимости от того, требуется ли ему детерминизм реального времени или нет. Инструменты разработки для этих приложений в значительной степени различны. Перенос исходных кодов между этими средами весьма сложен. И опять таки, требование к объему памяти для этой среды значительно выше, чем просто к Windows NT.

Несмотря на недостатки обоих методов, появление возможности добавить, в некоторой степени, поддержку реального масштаба времени в стандартный Windows NT имеет положительную сторону - в особенности то, что совместимость с Windows NT в основном сохраняется. Тем не менее, так как оба метода добавляют собственные интерфейсы, они сводят на нет дух цельной среды “открытой системы”, которая бережно создавалась в течение нескольких последних лет.

Вместо того чтобы брать ОС (Windows NT), исходные коды которой не доступны, и пытаться добавить в нее возможности реального времени, намного лучше заставить работать приложения Win32 на ОС, специально созданной для работы в реальном масштабе времени. Пример такого метода - это реализация инструментального пакета Willows Win32 в среде операционной системы QNX ® , построенной на базе микроядра.

Добавление Win32 API в ОС реального времени.

В попытке ввести в мир Win32 те полезные возможности, которые POSIX внес в окружение систем UNIX, Европейская Ассоциация Производителей Компьютеров (European Computer Manufacturers Association или ECMA) утвердила Интерфейс Программирования Приложений для Windows (Application Programming Interface for Windows или APIW). Так же как группы стандартов POSIX определили POSIX исключительно в пределах интерфейса, а не в пределах реализации, так и ECMA вместе с OSF определили стандарт APIW. Назначение APIW - определить стандарт интерфейса Win32 для разработки в открытых системах кросс платформенных программ, которые не обязательно должны работать только в операционных системах, зависящих от Microsoft или Intel.

ОС QNX подтверждает состоятельность этого “независимого от реализации” метода: это высокопроизводительная ОС на базе микроядра, которая также поддерживает интерфейс стандарта POSIX. Как и POSIX API, APIW, определенный ECMA, может быть принят QNX, позволяя ОС обеспечивать высокопроизводительную платформу реального времени для работы приложений, написанных для Win32 API. Такой подход устраняет множество недостатков, описанных для двух предыдущих методов:

Устойчивая среда

    QNX представляет модель среды исполнения, по крайней мере, такой же степени надежности, как и Windows NT, с процессами, выполняющимися в отдельных MMU-защищенных адресных пространствах. И как результат, среда реального времени, которую QNX предоставляет для Win32 программ, более “жесткая” чем среда, в которой выполняются HAL- резидентные задачи без защиты памяти:

Совместимость стандартной среды и среды реального времени

    Приложения реального масштаба времени могут быть написаны с полной поддержкой Win32 API, включая доступ к графическому интерфейсу. Это намного предпочтительнее, чем иметь только ограниченный API внутри HAL или собственный API, управляемый ОС, которая запускает NT как задачу. Разработчикам не нужно изучать новый набор функций и средства разработки, и уже существующий исходный код Win32 может быть немедленно откомпилирован и запущен в среде реального времени.

Нет накладных расходов

    QNX, как событийно-управляемая ОС реального времени, не нуждается в опросе этих событий. ОС отвечает на аппаратные прерывания только тогда, когда они происходят, запуская обработчик прерываний и распределяя процессы, затрачивая на это минимум времени, как это и свойственно ОС реального времени. Таким образом, исключаются излишние задержки и дополнительные затраты ресурсов, связанные с опросом событий реального времени.

Компактная платформа

    Реализация Win32 API в QNX, выражается в том, что среда исполнения получается компактнее, чем Windows 95, и значительно компактнее, чем Windows NT. Несмотря на свою компактность, эта среда обеспечивает устойчивость полной защиты памяти, в дополнение к детерминизму реального времени, поддержке Win32 API и POSIX API. Это удовлетворяет встраиваемые в ПЗУ или в flash-память системы намного больше, чем настольные ОС типа Windows NT.

Эта среда дает дополнительную выгоду: благодаря совместимости QNX со стандартами POSIX и UNIX, исходный код UNIX систем может быть также откомпилирован и запущен. Перенос исходных кодов UNIX на QNX платформу требует такой же объем затрат, как и перенос исходных кодов между разными версиями UNIX от разных производителей. В результате, разработчики системы реального времени могут спокойно переносить исходный код как из мира Win32, так и из мира UNIX прямо в свою среду реального времени. Это минимизирует объем кода, который должен быть написан с нуля, и что более важно, помогает сократить время выхода продукта на рынок.

Реализация Win32 API в QNX

Для реализации Win32 API в ОС QNX, Willows Software () и QNX Software Systems перенесли пакет Willows RT в QNX и добавили оптимизацию для QNX, для лучшей работы окружения Willows. Этот пакет работает как независимый от платформ интерфейс между приложениями, вызывающими Win32 API и основной операционной системой. С точки зрения прикладных программ, этот интерфейс, выполненный как разделяемая библиотека, выступает в виде оперативной среды Windows со всеми ее возможностями и функциями, которые программа ожидает увидеть. С точки зрения разработчика, нет необходимости овладевать новой средой для рекомпиляции существующих приложений Win32.

Willows RT изначально был разработан как Willows Toolkit для X Window System for Unix и для графической среды Macintosh. Несмотря на то, что существует реализация X Window для QNX, работа Willows RT под X в среде QNX не удовлетворила бы требованиям компактности для рынка встраиваемых систем реального времени. Итак, Willows RT был перенесен в оконную систему на базе микроядра - Photon microGUI ® , которая работает в среде QNX (смотрите Error! Reference source not found. для более подробной информации). Photon может выполнять те же функции, что и X Window, но занимает меньший объем памяти (около 500Кб). Наряду с маленьким размером самой QNX, он открывает новое решение - Willows-на-QNX, которое требует намного меньше памяти, чем Windows NT и дает возможность работать приложениям Win32 в реальном масштабе времени.

Компоненты Willows API

В Willows API входят 3 основные компоненты:

  • бинарный интерфейс Willows (Willows Binary Interface)
  • библиотека Willows (Willows Library)
  • уровень абстракции платформы Willows (Willows Platform-abstraction Layer)

Бинарный интерфейс Willows

Приложения Win32 взаимодействуют с библиотекой Willows таким же образом как и со средой Windows: вызов функций API, прием сообщений, загрузка ресурсов и даже запуск других приложений Win32. Существующие приложения Win32 и динамические библиотеки (DLLs) для доступа к Win32 API на не-Intel платформах взаимодействуют с бинарным интерфейсом Willows. (Этот интерфейс перенаправляет все запросы Windows API к библиотеке Willows, чтобы дать возможность инородным приложениям достигнуть скорости функционирования как на родной платформе.) Подобным же образом, библиотека Willows взаимодействует с областью драйверов, создавая запросы к графическим, оконным или системным операциям и принимая ответы или асинхронные сообщения.

Willows API может опознавать 16-ти разрядные Intel объекты, такие как динамические библиотеки (DLL), директивы Visual Basic (VBX), драйверы (DRV) и пользовательские средства управления произведенные “третьими фирмами”. Следовательно, разработчики могут совмещать в прикладной программе исходные коды и бинарные модули. Также, они могут переносить свои приложения, не дожидаясь, когда кто-нибудь из “третьих фирм” перенесет свои библиотеки. Файлы данных и графические файлы могут также использоваться без всяких изменений и программы могут продолжать загружать данные из DLL без каких-либо модификаций, что ускорит продвижение продукта на рынок.

Виртуальная Машина

    Виртуальная Машина обеспечивает слой абстрагирования от аппаратного обеспечения, который имитирует работу Intel процессора в защищенном режиме. Этот слой управляет сегментами кода и данных, регистрами Intel, управлением прерываний, инструкциями и имитацией ввода/вывода. Все исходные адреса отображаются в адреса в формате сегмент/смещение, включая адреса данных и адреса функций окна Windows API.

    Для переноса Willows RT в QNX, для которой Intel процессор является родным, такая адаптация к аппаратному обеспечению не нужна. В результате этого, родной код Wn32 может работать с требуемой скоростью, не зависимо от того, производился ли перенос исходного кода Win32 или изменилась среда функционирования DLLs, для которых исходный код не доступен. Такое естественное выполнение сохраняет способности программ достигать производительности реального масштаба времени на ОС QNX.

Эмулятор DOS

    Эмулятор DOS имитирует прерывания и функциональный интерфейс DOS. Сюда включены все функции DOS, используемые Win32 API, включая управление процессами и операции ввода-вывода. Доступ к параллельным и последовательным портам производится путем отображения функций непосредственно на устройства или фильтры вывода.

    QNX поддерживает доступ к родным носителям информации DOS, которые Willows RT использует, чтобы читать и записывать файлы на такие носители как жесткие и гибкие диски. В результате, файлы могут спокойно перемещаться между системами QNX/Willows и родным окружением Windows/DOS. Сетевые соединения через TCP/IP c SMB (или CIFS) и NFS могут также использоваться для совместного использования сетевых файлов между системами QNX/Willows и Windows95 или Windows NT.

16/32-х битный Обработчик запросов

    16/32-х битный Обработчик запросов (16/32 Thunking Layer) манипулирует запросами между 16-битовым кодом Windows и библиотекой Willows. 16-битовый код работает в защищенном режиме, используя 16-битовый стек и сегмент/смещение для адресации. Каждый запрос идентифицируется “методом”, который обрабатывает соответствующий тип запроса. Данный метод может варьироваться от чего-нибудь простого, вроде таких как запрос к библиотеке и возвращение результата в определенных регистрах, до более сложных операций, которые преобразуют адреса и структуры данных в обоих случаях, как во время вызова, так и в момент возврата из процедуры.

16/32-битный Загрузчик

    16/32-битный Загрузчик загружает программы, производит распределение кода и данных программ, динамических библиотек и драйверов. Загрузчик работает совместно с виртуальной машиной и обработчиком запросов, для размещения сегментов кода и данных, включая отсутствующие сегменты, которые будут загружены в дальнейшем по запросам приложений. Загрузчик также связывает библиотеку Willows с DLL для переназначения вызовов к библиотеке.

Библиотека Willows

Для реализации Microsoft Windows API, библиотека Willows была сделана независимой от платформы, отделяя зависящий от платформы код от самой библиотеки, и помещая его на более низкий уровень абстрагирования от платформы. Для полной гарантии независимости от платформы, библиотека была написана с помощью самого Win32 API; это сократило до минимума число функций, которые необходимо поместить на уровень абстрагирования от платформы. В результате, библиотека Willows остается совместимой со многими платформами, компилируясь как родной код для каждой из платформ, для достижения максимальной эффективности.

Реализация библиотеки Willows согласована и совместима с требованиями APIW, введенного ECMA и OSF как кросс платформенный Windows API. Она написана на языке C и обеспечивает доступ как из программ, написанных на C, так и на C++.

Все наиболее часто используемые функции Windows API, за исключением специфических функций запуска двоичных программ, реализованы в Бинарном Интерфейсе. Он включает все стандартные функции управления и классы, такие как классы типов и сообщений.

Библиотека поддерживает:

  • окна MDI, общие диалоги и функции управления диалогами
  • реализацию многозадачности внутри одного процесса
  • буфер обмена (clipboard) и динамический обмен данными (DDE)

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

Эта среда также добавляет в Windows API полный набор функций конфигурации и отладки. Работая с версией библиотеки, предназначенной для отладки, прикладная программа может проследить выполнение каждого API и получить диагностическую информацию о программе, во время ее выполнения. Встроенный в библиотеку отладчик может работать самостоятельно или с обычными отладчиками для получения детальной информации в реальном масштабе времени о состоянии программы.

Уровень абстрагирования от платформы

Этот уровень содержит весь зависящий от платформы код для создания и управления окнами, отображения в этих окнах, и доступа к системно-зависимым ресурсам. Он содержит три подсистемы, которые доступны через вызовы библиотеки Willows:

Интерфейс администратора окон

    Интерфейс администратора окон позволяет библиотеке управлять - в независимом от платформы стиле - всеми окнами, которые создает прикладная программа. Он управляет такими функциями как создание и удаление окон, смена размера и перенос окон, создание и обслуживание меню управления окна, установка заголовков и иконок для минимизированных окон.

    Вся связь с менеджером рабочего стола (desktop window manager) производится кодом, приспособленным для конкретной платформы, который затем переправляет информацию независимой от платформы части администратора окон. Большинство внешних событий, доступ к которым из графических программ обеспечивает Photon, также перехватываются на этом уровне и преобразуются в стандартный набор команд, которые может обрабатывать библиотека. К таким событиям относятся сообщения о создании, перерисовке и удалении окон и сообщения о местоположении и размере окон.

Интерфейс графических устройств

    Интерфейс графических устройств (Graphics Device Interface) обеспечивает средства для вывода изображений непосредственно в окна или на принтеры. Он поддерживает основные графические операции, такие как рисование линий, прямоугольников и эллипсов, а также более сложные операции над объектами, такими как перо, кисть, регион и графический образ. Он также имеет полный набор функций для вывода текста, от выбора шрифта и цвета до специальных эффектов, таких как подчеркивание и перечеркивание. Библиотека Willows и Интерфейс Графических Устройств поддерживают широкий спектр устройств, от простейших с малой разрешающей способностью и ограниченной цветовой гаммой, до дисплеев с высокой разрешающей способностью и большим количеством цветов, а также большой набор принтеров. Все эти услуги отображаются непосредственно на средства, предоставляемые Photon microGUI.

Интерфейс системных услуг

    Интерфейс системных услуг (System Services Interface) обеспечивает зависимый от платформы код для доступа к средствам файловой системы, распределения памяти, сетевого взаимодействия и доступа к устройствам. Например, он перекладывает все запросы, связанные с работой в сети и коммуникациями на соответствующие функции, предоставляемые операционной системой QNX. Он также поддерживает функции межзадачного обмена (IPC), такие как clipboard и DDE, реализованные в библиотеке Willows. Кроме того, он содержит зависимый от платформы код, ассоциируемый с динамическими библиотеками, и позволяющий библиотеке окон Willows (Willows Window Library) поддерживать в QNX семантику динамически загружаемых библиотеки.

Взаимосвязь между платформами Win32

Так как Вы можете спокойно переносить приложения Win32 между Windows и QNX, то становится относительно просто создавать распределенные системы реального времени, где каждый узел в сети может работать под управлением той ОС, которая в большей степени удовлетворяет желаниям пользователя, но где все узлы используют один и тот же API и коды прикладных программ. Конечно, теперь, когда программа, построенная из одних и тех же исходных кодов Win32, может работать в различных операционных системах одной локальной сети, становится важным обеспечение взаимосвязи этих распределенных программ. Отвечая этому требованию, QXN поддерживает сетевые файловые системы SMB (CIFS) и NFS. Более того, Photon microGUI дает Вам возможность просматривать и управлять экраном узла QNX (или окном конкретного приложения) с экрана Windows 95 или Windows NT. В результате, графические приложения реального времени могут работать на платформах жесткого реального времени, а отображаться на обычных системах, подключенных к сети.

Дополнительные услуги QNX

Как ОС реального времени на базе микроядра, QNX предлагает приложениям Win32 набор услуг, не доступных в Windows NT. Сюда входит устойчивое быстродействие в реальном масштабе времени, распределенная обработка данных и отказоустойчивая сеть.

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

Для обеспечения максимальной производительности и отказоустойчивости сети, QNX поддерживает множественные сетевые соединения для каждого компьютера сети. QNX будет автоматически распределять нагрузку на сети, и при выходе из строя какого-либо сетевого соединения, перенаправлять данные по действующим сетям.

Заключение

Очевидно, методы HAL-расширения и управляющей ОС предлагают работоспособные варианты добавления возможностей реального времени в NT, но за определенную цену. Они заставляют разработчиков работать с дополнительными, доморощенными API и нестандартными средствами разработки. Они запускают задачи реального времени в относительно неустойчивой среде. К тому же, они увеличивают требования к памяти, которые у NT и без того не маленькие.

С другой стороны, реализация Win32 API на ОС реального времени QNX, позволяет разработчикам использовать только один API - Win32. Это позволяет процессам реального времени работать в надежной, отлаженной среде. И, благодаря малой требовательности QNX к объему оперативной памяти, появляется возможность использовать Win32 для небольших встраиваемых систем.

Как тщательно продуманная ОС реального времени, оптимизированная для использования в критичных к сбоям приложениях, QNX также предлагает разработчику дополнительные возможности - такие как отказоустойчивость сети, распределенная обработка информации и полная совместимость с POSIX и UNIX, что практически не возможно в NT. Более того, QNX делает относительно простым объединение платформ Win32, которое дает разработчику свободу выбора соответствующей ОС для каждой задачи. И в конечном итоге, разработка Willows/QNX представляет объединение менталитета “отрытых систем” и стандартов переносимости исходных кодов.

QNX и Photon microGUI являются зарегистрированными торговыми знаками QNX Software Systems.
Все другие торговые знаки и зарегистрированные торговые знаки принадлежат соответствующим владельцам.

Windows API - набор функций операционной системы

Аббревиатура API многим начинающим программистам кажется весьма таинственной и даже пугающей. На самом же деле Application Programming Interface (API) - это просто некоторый готовый набор функций, который могут использовать разработчики приложений. В общем случае данное понятие эквивалентно тому, что раньше чаще называли библиотекой подпрограмм. Однако обычно под API подразумевается особая категория таких библиотек.

В ходе разработки практически любого достаточно сложного приложения (MyAppication) для конечного пользователя формируется набор специфических внутренних функций, используемых для реализации данной конкретной программы, который называется MyApplication API. Однако часто оказывается, что эти функции могут эффективно использоваться и для создания других приложений, в том числе другими программистами. В этом случае авторы, исходя из стратегии продвижения своего продукта, должны решить вопрос: открывают они доступ к этому набору для внешних пользователей или нет? При утвердительном ответе в описании программного пакета в качестве положительной характеристики появляется фраза: «Комплект включает открытый набор API-функций» (но иногда за дополнительные деньги).

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

Соответственно Windows API - это набор функций, являющийся частью самой операционной системы и в то же время - доступный для любого другого приложения, в том числе написанного с помощью VB. В этом плане вполне оправданна аналогия с набором системных прерываний BIOS/DOS, который фактически представляет собой DOS API.

Отличие заключается в том, что состав функций Windows API, с одной стороны, значительно шире по сравнению с DOS, с другой - не включает многие средства прямого управления ресурсами компьютера, которые были доступны программистам в предыдущей ОС. Кроме того, обращение к Windows API выполняется с помощью обыкновенных процедурных обращений, а вызов функций DOS - через специальную машинную команду процессора, которая называется Interrupt («прерывание»).

Зачем нужен Win API для VB-программистов

Несмотря на то что VB обладает огромным множеством разнообразных функций, в процессе более-менее серьезной разработки обнаруживается, что их возможностей зачастую не достаточно для решения необходимых задач. При этом программисты-новички часто начинают жаловаться на недостатки VB и подумывать о смене инструмента, не подозревая, что на их компьютере имеется огромный набор средств и нужно только уметь ими воспользоваться.

При знакомстве с Win API обнаруживается, что многие встроенные VB-функции - не что иное, как обращение к соответствующим системным процедурам, но только реализованное в виде синтаксиса данного языка. С учетом этого необходимость использования API определяется следующим вариантами:

  1. API-функции, которые полностью реализованы в виде встроенных VB-функций. Тем не менее иногда и в этом случае бывает полезным перейти к применению API, так как это позволяет порой существенно повысить производительность (в частности, за счет отсутствия ненужных преобразований передаваемых параметров).
  2. Встроенные VB-функции реализуют лишь частный случай соответствующей API-функции. Это довольно обычный вариант. Например, API-функция CreateDirectory обладает более широкими возможностями по сравнению со встроенным VB-оператором MkDir.
  3. Огромное число API-функций вообще не имеет аналогов в существующем сегодня варианте языка VB. Например, удалить каталог средствами VB нельзя - для этого нужно использовать функцию DeleteDirectory.

Следует также подчеркнуть, что некоторые API-функции (их доля в Win API весьма незначительна) не могут вызываться из VB-программ из-за ряда ограничений языка, например из-за отсутствия возможности работы с адресами памяти. Но в ряде случаев могут помочь нетривиальные приемы программирования (в частности, в случае с теми же адресами).

Личная точка зрения автора такова - вместо расширения от версии к версии встроенных функций VВ следовало бы давать хорошее описание наиболее ходовых API-функций. В то же время хочется посоветовать разработчикам не ждать появления новой версии средства с расширенными функциями, а внимательнее изучить состав существующего Win API - вполне вероятно, что нужные вам возможности можно было реализовать уже в версии VB 1.0 выпуска 1991 года.

Как изучать Win API

Это не такой простой вопрос, если учесть, что число функций Win32 API оценивается величиной порядка 10 тысяч (точной цифры не знает никто, даже Microsoft).

В состав VB (версий 4-6) входит файл с описанием объявлений Win API - WIN32API.TXT (подробнее о его применении мы расскажем позднее). Но, во-первых, с его помощью можно получить сведения о назначении той или иной функции и ее параметрах только по используемым мнемоническим именам, а во-вторых - перечень функций в этом файле далеко не полный. В свое время (семь лет назад) в VB 3.0 имелись специальные справочные файлы с описанием функций Win16 API. Однако уже в v.4.0 эта полезная информация с удобным интерфейсом исчезла.

Исчерпывающую информацию о Win32 API можно найти в справочной системе Platform Software Development Kit, которая, в частности, находится на компакт-дисках MSDN Library, включенных в состав VB 5.0 и 6.0 Enterprise Edition и Office 2000 Developer Edition. Однако разыскать там нужную информацию и разобраться в ней совсем не просто. Не говоря уж о том, что все описания там приводятся применительно к языку C.

Общепризнанным в мире пособием для изучения API-программирования в среде VB являются книги известного американского эксперта Даниэля Эпплмана (Daniel Appleman). Его серия Dan Appleman’s Visual Basic Programmer’s Guide to the Windows API (для Win16, Win32, применительно к разным версиям VB) с 1993 года неизменно входит в число бестселлеров для VB-программистов. Книгу Dan Appleman’s VB 5.0 Programmer’s Guide to the Win32 API, выпущенную в 1997 году, автору привез из США приятель, который нашел ее в первом же книжном магазине небольшого провинциального городка.

Эта книга объемом свыше 1500 страниц включает описание общей методики API-программирования в среде VB, а также более 900 функций. Прилагаемый компакт-диск содержит полный текст книги и всех программных примеров, а кроме того, несколько дополнительных глав, не вошедших в печатный вариант. В 1999 году Дэн Эпплман выпустил новую книгу Dan Appleman’s Win32 API Puzzle Book and Tutorial for Visual Basic Programmers, которая включает сведения о еще 7600 функциях (хотя и не столь обстоятельные).

Win API и Dynamic Link Library (DLL)

Набор Win API реализован в виде динамических DLL-библиотек. Далее речь фактически пойдет о технологии использования DLL в среде VB на примере библиотек, входящих в состав Win API. Однако, говоря о DLL, необходимо сделать несколько важных замечаний.

В данном случае под DLL мы подразумеваем традиционный вариант двоичных динамических библиотек, которые обеспечивают прямое обращение приложений к нужным процедурам - подпрограммам или функциям (примерно так же, как это происходит при вызове процедур внутри VB-проекта). Такие библиотеки могут создаваться с помощью разных инструментов: VC++, Delphi, Fortran, кроме VB (посмотрим, что появится в версии 7.0) - последний может делать только ActiveX DLL, доступ к которым выполняется через интерфейс OLE Automation.

Обычно файлы динамических библиотек имеют расширение.DLL, но это совсем не обязательно (для Win16 часто применялось расширение.EXE); драйверы внешних устройств обозначаются с помощью.DRV.

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

А теперь несколько советов.

Совет 1. Следите за правильным оформлением объявления DL L-процедур

Само обращение к DLL-процедурам в программе выглядит точно так же, как к «обычным» процедурам Visual Basic, например:

Call DllName ([список аргументов])

Однако для использования внешних DLL-функций (в том числе и Win API) их нужно обязательно объявить в программе с помощью оператора Declare, который имеет следующий вид:

Declare Sub ИмяПроцедуры Lib _ “ИмяБиблиотеки” _ [([СписокАргументов])]

Declare Function ИмяФункции _ Lib “ИмяБиблиотеки” _ [([СписокАргументов])]

Здесь в квадратных скобках приведены необязательные элементы оператора, курсивом выделены переменные выражения, остальные слова - ключевые. В справочной системе приведено достаточно хорошее описание синтаксиса оператора, поэтому сейчас мы только отметим некоторые моменты.

Объявления внешних функций должны размещаться в секции General Declarations модуля. Если вы размещаете его в модуле формы, то обязательно нужно указать ключевое слово Private (это объявление будет доступно только внутри данного модуля) - таково ограничение для всех процедур модуля формы.

Набор Win32 API реализован только в виде функций (в Win16 API было много подпрограмм Sub). В большинстве своем - это функции типа Long, которые чаще всего возвращают код завершения операции.

Оператор Declare появился в MS Basic еще во времена DOS, причем он использовался и для объявления внутренних процедур проекта. В Visual Basic этого не требуется, так как объявлением внутренних процедур автоматически является их описание Sub или Function. По сравнению с Basic/DOS в новом описании обязательно указывать имя файла-библиотеки, где находится искомая процедура. Библиотеки Wip API размещаются в системном каталоге Windows, поэтому достаточно привести только название файла. Если же вы обращаетесь к DLL, которая находится в произвольном месте, нужно записать полный путь к данному файлу.

Описание оператора Declare обычно занимает довольно много места и не помещается в одну строку в окне кода. Поэтому мы рекомендуем придерживаться при написании приложений какой-либо определенной схемы переноса строк, например:

Declare Function GetTempPath _ Lib “kernel32” Alias “GetTempPathA” _ (ByVal nBufferLength As Long, _ ByVal lpBuffer As String) As Long

В этом случае все основные элементы описания разнесены на разные строчки и поэтому хорошо читаются.

Совет 2. Будьте особенно внимательны при работе с DLL-функциями

Использование Win API и разнообразных DLL-функций существенно расширяет функциональные возможности VB и зачастую позволяет повысить производительность программ. Однако расплата за это - риск снижения надежности работы приложения, особенно в процессе его отладки.

Одним из самых важных достоинств среды VB является надежность процесса разработки программ: функционируя под управлением интерпретатора, программный код теоретически не может нарушить работу Windows и самого VB. Программист может не очень внимательно следить за правильностью передачи параметров в вызываемые функции - подобные ошибки будут легко обнаружены самим интерпретатором либо в процессе трансляции кода, либо во время его выполнения. В самом неприятном случае просто произойдет прерывание режима обработки, причем с указанием, где и почему произошла ошибка.

Использование напрямую функций Windows API или других DLL-библиотек снимает такой контроль за передачей данных и процессом выполнения кода вне среды VB. Поэтому ошибка в обращении к внешним функциям может привести к неработоспособности и VB и операционной системы. Это особенно актуально на этапе разработки программы, когда наличие ошибок - дело вполне естественное. Таким образом, применяя более широкие возможности функций базового слоя системы, программист берет на себя ответственность за правильность их применения.

Проблема усугубляется еще и тем, что разные языки программирования используют различные способы передачи параметров между процедурами. (Точнее, разные способы передачи используются по умолчанию, так как многие языки могут поддерживать несколько способов.) Win API реализованы на C/C++ и применяют соглашения о передаче параметров, принятые в этой системе, которые отличаются от привычного для VB варианта.

В связи с этим следует отметить, что появление встроенных в VB аналогов API-функций оправданно именно адаптацией последних к синтаксису VB и реализацией соответствующего механизма контроля обмена данными. Обратим также внимание, что на этапе опытной отладки приложения при создании исполняемого модуля лучше использовать вариант компиляции P-code вместо Native Code (машинный код). В первом случае программа будет работать под управлением интерпретатора - медленнее по сравнению с машинным кодом, но более надежно с точки зрения возможного ошибочного воздействия на операционную систему и обеспечивая более удобный режим выявления возможных ошибок.

Совет 3. Десять рекомендаций Дэна Эпплмана по надежному API-программированию в среде VB

Использование функции API требует более внимательного программирования с использованием некоторых не очень привычных методов обращения к процедурам (по сравнению с VB). Далее мы будем постоянно обращаться к этим вопросам. А сейчас приведем изложение сформулированных Дэном Эпплманом советов на эту тему (их первый вариант появился еще в 1993 году) с некоторыми нашими дополнениями и комментариями.

1. Помните о ByVal. Наиболее частая ошибка, совершаемая при обращении к функциям API и DLL, заключается в некорректном использовании ключевого слова ByVal: его или забывают ставить, или, наоборот, ставят, когда в нем нет необходимости.

На этих примерах показано влияние оператора ByVal на передачу параметров

Тип параметра С ByVal Без ByVal
Integer В стек помещается 16-разрядное целое В стек помещается 32-разрядный адрес 16-разрядного целого
Long В стек помещается 32-разрядное целое В стек помещается 32-разрядный адрес 32-разрядного целого
String Строка преобразуется в формат, используемый в С (данные и завершающий нулевой байт). 32-разрядный адрес новой строки помещается в стек В стек помещается VB-дескриптор строки. (Такие дескрипторы никогда не используются самим Windows API и распознаются только в DLL, реализованных специально для VB.)

Здесь следует напомнить, что передача параметров в любой системе программирования, в том числе и VB, выполняется двумя основными путями: по ссылке (ByRef) или по значению (ByVal). В первом случае передается адрес переменной (этот вариант используется в VB по умолчанию), во втором - ее величина. Принципиальное отличие заключается в том, что с помощью ссылки обеспечивается возврат в вызывающую программу измененного значения передаваемого параметра.

Чтобы разобраться в этом, проведите эксперимент с помощью таких программ:

Dim v As Integer v = 2 Call MyProc(v) MsgBox “v = “ & v Sub MyProc (v As Integer) v = v + 1 End Sub

Запустив на выполнение этот пример, вы получите сообщение со значением переменной, равным 3. Дело в том, что в данном случае в подпрограмму MyProc передается адрес переменной v, физически созданной в вызывающей программе. Теперь измените описание процедуры на

Sub MyProc (ByVal v As Integer)

В результате при выполнении теста вы получите v = 2, потому что в процедуру передается лишь исходное значение переменной - результат выполненных с ним операций не возвращается в вызывающую программу. Режим передачи по значению можно поменять также с помощью оператора Call следующим образом:

Sub MyProc (v As Integer) ... Call MyProc((v)) ‘ (v) - скобки указывают режим _ передачи по значению.

Однако при обращении к внутренним VB-процедурам использование в операторе Call ключевого слова ByVal запрещено - вместо него применяются круглые скобки. Этому есть свое объяснение.

В классическом случае (С, Fortran, Pascal) различие режимов ByRef и ByVal зависит от того, что именно помещается в стек обмена данными - адрес переменной или ее значение. В Basic исторически используется вариант программной эмуляции ByVal - в стеке всегда находится адрес, но только при передаче по значению для этого создается временная переменная. Чтобы отличить два этих варианта (классический и Basic), используются разные способы описания режима ByVal. Отметим, что эмуляция режима ByVal в VB обеспечивает более высокую надежность программы: перепутав форму обращения, программист рискует лишь тем, что в вызывающую программу вернется (или не вернется) исправленное значение переменной. В «классическом» же варианте такая путаница может привести к фатальной ошибке при выполнении процедуры (например, когда вместо адреса памяти будет использоваться значение переменной, равное, скажем, нулю).

DLL-функции реализованы по «классическим» принципам и поэтому требуют обязательного описания того, каким образом происходит обмен данными с каждым из аргументов. Именно этой цели служат объявления функций через описание Declare (точнее, списка передаваемых аргументов). Чаще всего передача параметров в функцию Windows API или DLL выполняется с помощью ключевого слова ByVal. Причем оно может быть задано как в операторе Declare, так и непосредственно при вызове функции.

Последствия неправильной передачи параметров легко предугадать. В случае получения явно недопустимого адреса вам будет выдано сообщение GPF (General Protection Fault - ошибка защиты памяти). Если же функция получит значение, совпадающее с допустимым адресом, то функция API залезет в чужую область (например, в ядро Windows) со всеми вытекающими отсюда катастрофическими последствиями.

2. Проверяйте тип передаваемых параметров. Не менее важны верное число и тип передаваемых параметров. Необходимо, чтобы объявленные в Declare аргументы соответствовали ожидаемым параметрам в функции API. Наиболее часто встречающийся случай ошибки в передаче параметров связан с различием между NULL и строкой нулевой длины - следует помнить, что это не одно и то же.

3. Проверяйте тип возвращаемого значения.

VB довольно терпимо относится к несовпадению типов возвращаемых функцией значений, поскольку числовые значения обычно возвращаются через регистры, а не через стек. Следующие правила помогут определить корректное значение, возвращаемое функцией API:

  • DLL-функция, не возвращающая значения (аналог void в ‘C’), должна быть объявлена как VB Sub.
  • функция API, возвращающая целое значение (Integer или Long), может быть определена или как Sub, или как Function, возвращающая значение соответствующего типа.
  • ни одна из функций API не возвращает числа с плавающей точкой, но некоторые DLL вполне могут возвращать такой тип данных.

4. С большой осторожностью используйте конструкцию «As Any». Множество функций Windows API имеют возможность принимать параметры различных типов и используют при этом обращение с применением конструкции As Any (интерпретация типа выполняется в зависимости от значения других передаваемых параметров).

Хорошим решением в этом случае может быть использование нескольких псевдонимов (Alias) функции с созданием двух и более объявлений для одной и той же функции, причем в каждом из описаний указываются параметры определенного типа.

5. Не забывайте инициализировать строки. В Win API существует множество функций, возвращающих информацию путем загрузки данных в передаваемые как параметр строковые буферы. В своей программе вы можете вроде бы все сделать правильно: не забыть о ByVal, верно передать параметры в функцию. Но Windows не может проверить, насколько велик размер выделенного под строку участка памяти. Размер строки должен быть достаточным для размещения всех данных, которые могут быть в него помещены. Ответственность за резервирование буфера нужного размера лежит на VB-программисте.

Следует отметить, что в 32-разрядных Windows при использовании строк производится преобразование из Unicode (двухбайтовая кодировка) в ANSI (однобайтовая) и обратно, причем с учетом национальных установок системы. Поэтому для резервирования буферов порой удобнее использовать байтовые массивы вместо строковых переменных. (Подробнее об этом будет рассказано ниже.)

Чаще всего функции Win API позволяют вам самим определить максимальный размер блока. В частности, иногда для этого нужно вызвать другую функцию API, которая «подскажет» размер блока. Например, GetWindowTextLength позволяет определить размер строки, необходимый для размещения заголовка окна, получаемого функцией GetWindowText. В этом случае Windows гарантирует, что вы не выйдете за границу.

6. Обязательно используйте Option Explicit.

7. Внимательно проверяйте значения параметров и возвращаемых величин. VB обладает хорошими возможностями по проверке типов. Это означает, что, когда вы пытаетесь передать неверный параметр в функцию VB, самое плохое, что может случиться, - вы получите сообщение об ошибке от VB. Но данный механизм, к сожалению, не работает при обращении к функциям Windows API.

Windows 9x обладает усовершенствованной системой проверки параметров для большинства функций API. Поэтому наличие ошибки в данных обычно не вызывает фатальной ошибки, однако определить, что же явилось ее причиной - не так-то просто.

Здесь можно посоветовать использовать несколько способов отладки ошибки данного типа:

  • используйте пошаговый режим отладки или команду Debug.Print для проверки каждого подозрительного вызова функции API. Проверьте результаты этих вызовов, чтобы удостовериться, что все в пределах нормы и функция корректно завершилась;
  • используйте Windows-отладчик типа CodeView и отладочную версию Windows (имеется в Windows SDK). Эти средства могут обнаружить ошибку параметров и по меньшей мере определить, какая функция API приводит к ошибке;
  • используйте дополнительные средства третьих фирм для проверки типов параметров и допустимости их значений. Такие средства могут не только находить ошибки параметров, но даже указать на строку кода VB, где произошла ошибка.

Кроме того, нужно обязательно проверять результат выполнения API-функции.

8. Помните, что целые числа в VB и в Windows - не одно и то же. В первую очередь следует иметь в виду, что под термином «Integer» в VB понимается 16-разрядное число, в документации Win 32 - 32-разрядное. Во-вторых, целые числа (Integer и Long) в VB - это величины со знаком (то есть один разряд используется как знак, остальные - как мантисса числа), в Windows - используются только неотрицательные числа. Это обстоятельство нужно иметь в виду, когда вы формируете передаваемый параметр с помощью арифметических операций (например, вычисляете адрес с помощью суммирования некоторой базы и смещения). Для этого стандартные арифметические функции VB не годятся. Как быть в этом случае, мы поговорим отдельно.

9. Внимательно следите за именами функций. В отличие от Win16 имена всех функций Win32 API являются чувствительными к точному использованию строчных и прописных букв (в Win16 такого не было). Если вы где-то применяете строчную букву вместо прописной или наоборот, то нужная функция не будет найдена. Следите также за правильным использованием суффикса A или W в функциях, применяющих строковые параметры. (Подробнее об этом – см. ниже.)

10. Чаще сохраняйте результаты работы. Ошибки, связанные с неверным использованием DLL и Win API, могут приводить к аварийному завершению работы VB-среды, а возможно - и всей операционной системы. Вы должны позаботиться о том, чтобы написанный вами код перед тестовым запуском был сохранен. Самое простое - это установить режим автоматической записи модулей проекта перед запуском проекта в среде VB.

После прочтения предыдущего совета может возникнуть мысль, что использование функций Win API - дело рискованное. В какой-то степени это так, но только в сравнении с безопасным программированием, предоставляемым самим VB. Но при умелом их применении и знании возможных подводных камней этот риск минимален. К тому же полностью отказаться от применения Win API зачастую просто невозможно - они все равно потребуются при сколь-нибудь серьезной разработке.

К тому же ранее мы упоминали о «подводных» камнях для широкого класса DLL. В случае с Win API все обстоит гораздо проще, так как здесь четко унифицирована форма обращения к этим функциям. При этом следует иметь в виду следующие основные моменты:

  1. Функции Win32 API являются именно функциями, то есть процедурами типа Function (в Win16 API было много подпрограмм Sub). Все это функции типа Long, поэтому их описания записываются в следующем виде: Declare Function name ... As Long ‘ тип функции _ определяется в явном виде

    Declare Function name& ‘ тип функции _ определяется с помощью суффикса

    Обращение к API-функции выглядит так:

Result& = ApiName& ([СписокАргументов ]
  1. Чаще всего возвращаемое значение функции является кодом завершения операции. Причем ненулевое значение означает в данном случае нормальное завершение, нулевое - ошибку. Обычно (но не всегда) уточнить характер ошибки можно с помощью обращения к функции GetLastError. Описание этой функции имеет такой вид: Declare Function GetLastError& Lib “kernel32” ()

    ВНИМАНИЕ! При работе в среде VB для получения значения уточненного кода ошибки лучше использовать свойство LastDLLError объекта Err, так как иногда VB обнуляет функцию GetLastError в промежутке между обращением к API и продолжением выполнения программы.

    Интерпретировать код, возвращаемый GelLastError, можно с помощью констант, записанных в файле API32.TXT, с именами, начинающимися с суффикса ERROR_.

    Наиболее типичные ошибки имеют следующие коды:

    • ERROR_INVALID_HANDLE = 6& - неверный описатель
    • ERROR_CALL_NOT_IMPLEMENTED = 120& - вызов в Windows 9x функции, доступной только для Windows NT
    • ERROR_INVALID_PARAMETER = 87& - неверное значение параметра

    Однако многие функции возвращают значение некоторого запрашиваемого параметра (например, OpenFile возвращает значение описателя файла). В таких случаях ошибка определяется каким-либо другим специальным значением Return&, чаще всего 0 или –1.

  2. Win32 API используют строго фиксированные способы передачи самых простых типов данных. а) ByVal ... As Long

    С помощью переменных типа Long выполняется не менее 80% передачи аргументов. Обратите внимание, что аргумент всегда сопровождается ключевым словом ByVal, а это, кроме всего прочего, означает, что выполняется односторонняя передача данных - от VB-программы к API-функции.

    Б) ByVal ... As String

    Этот тип передачи данных также встречается достаточно часто, причем с аргументом также всегда применяется ByVal. При вызове API-функции в стек записывается адрес строки, поэтому в данном случае возможен двусторонний обмен данными. При работе со строками нужно учитывать несколько опасностей.

    Первая - резервирование памяти под строку производится в вызывающей программе, поэтому если API-функция будет заполнять строки, то нужно перед ее вызовом создать строку необходимого размера. Например, функция GetWindowsDirectory возвращает путь к каталогу Windows, который по определению не должен занимать более 144 символов. Соответственно обращение к этой функции должно выглядеть примерно так:

    WinPath$ = Space$(144) ‘ резервируем строку в _ 144 символа Result& = GetWindowsDirectory& (WinTath$, 144) _ ‘заполнение буфера ‘ Result& - фактическое число символов в имени _ каталога WinPath$ = Left$(WinPath, Result&)

    Вторая проблема заключается в том, что при обращении к API-функции производится преобразование исходной строки в ее некоторое внутреннее представление, а при выходе из функции - наоборот. Если во времена Win16 эта операция заключалась лишь в добавлении нулевого байта в конце строки, то с появлением Win32 к этому добавилась трансформация двухбайтной кодировки Unicode в ANSI и наоборот. (Об этом подробно говорилось в статье «Особенности работы со строковыми переменными в VB», КомпьютерПресс 10’99 и 01’2000). Сейчас же только отметим, что с помощью конструкции ByVal ... As String можно обмениваться строками только с символьными данными.

    В) ... As Any

    Это означает, что в стек будет помещен некоторый адрес буфера памяти, интерпретация содержимого которого будет выполняться API-функцией, например, в зависимости от значения других аргументов. Однако As Any может использоваться только в операторе Declare - при конкретном обращении к функции в качестве аргумента должна быть определена конкретная переменная.

    Г) ... As UserDefinedType

    Такая конструкция также часто применяется, когда необходимо обменяться данными (в общем случае в обе стороны) с помощью некоторой структуры. На самом деле эта конструкция - некий вид конкретной реализации формы передачи As Any, просто в данном случае функция настроена на фиксированную структуру.

    Форма структуры данных определяется конкретной API-функцией, и на программисте лежит ответственность правильным образом описать и зарезервировать ее в вызывающей программе. Такая конструкция всегда используется без слова ByVal, то есть в данном случае выполняется передача по ссылке - в стек записывается адрес переменной.

Пример обращения к API-функции

Проиллюстрируем сказанное выше на примере использования двух полезных функций работы с файлами - lopen и lread, которые описываются следующим образом:

Declare Function lopen Lib “kernel32” _ Alias “_lopen” (_ ByVal lpFileName As String, _ ByVal wReadWrite As Long) As Long Declare Function lread Lib “kernel32” _ Alias “_lread” (_ ByVal hFile As Long, lpBuffer As Any, _ ByVal wBytes As Long) As Long

В VB их аналогами - в данном случае точными - являются операторы Open и Get (для режима Binary). Обратим сразу внимание на использование ключевого слова Alias в объявлении функции - это как раз тот случай, когда без него не обойтись. Настоящие названия функции в библиотеке начинаются с символа подчеркивания (типичный стиль для языка C), что не разрешается в VB.

Операция открытия файла может выглядеть следующим образом:

Const INVALID_HANDLE_VALUE = -1 ‘ неверное _ значение описателя lpFileName$ = “D:\calc.bas” ‘ имя файла wReadWrite& = 2 ‘ режим “чтения-записи” hFile& = lopen(lpFileName$, wReadWrite&) _ ‘ определяем описатель файла If hFile& = INVALID_HANDLE_VALUE Then _ ‘ ошибка открытия файла ‘ уточняем код ошибки CodeError& = Err.LastDllError ‘CodeError& = GetLastError _ ‘ эта конструкция не работает End If

Здесь нужно обратить внимание на два момента:

  • в качестве значения функции мы получаем значение описателя файла. Ошибке соответствует значение –1;
  • как раз в данном случае не срабатывает обращение к функции GetLastError - для получения уточненного значения ошибки мы обратились к объекту Err (о возможности такой ситуации мы говорили выше).

Далее можно читать содержимое файла, но это предполагает, что программист должен иметь некоторое представление о его структуре (так же как это происходит при работе с произвольными двоичными файлами). В этом случае обращение к функции lread может выглядеть следующим образом:

Dim MyVar As Single wBytes = lread (hFile&, MyVar, Len(MyVar) ‘ чтение вещественного числа, 4 байта ‘ wBytes - число фактически прочитанных данных, ‘ -1 - ошибка... Type MyStruct x As Single i As Integer End Type Dim MyVar As MyStruct wBytes = lread (hFile&, MyVar, Len(MyVar)) ‘ чтение структуры данных, 6 байтов

Еще раз обратите внимание: второй аргумент функции передается по ссылке, остальные - по значению.

Dim MyVar As String MyVar = Space$(10) ‘резервируем переменную для 10 символов wBytes = lread (hFile&, ByVal MyVar, Len(MyVar)) ‘ чтение символьной строки, 10 символов

Здесь видно важное отличие от приведенного ранее примера - строковая переменная обязательно сопровождается ключевым словом ByVal.

Чтение содержимого файла в массиве (для простоты будем использовать одномерный байтовый массив) выполняется следующим образом:

Dim MyArray(1 To 10) As Byte wBytes = lread (hFile&, MyArray(1), _ Len(MyArray(1))* 10) ‘ чтение 10 элементов массива

Указывая первый элемент массива в качестве аргумента, мы передаем адрес начала области памяти, зарезервированной под массив. Очевидно, что таким образом можно заполнить любой фрагмент массива:

WBytes = lread (hFile&, MyArray(4), _ Len(MyArray(1))* 5) ‘ чтение элементов массива с 4-го по 8-й

Совет 5. Используйте Alias для передач и параметров As Any

Здесь на основе предыдущего примера мы раскроем суть четвертого совета Дэна Эпплмана.

Работая с функцией lread, следует помнить, что при обращении к ней с использованием строковой переменной необходимо использовать ключевое слово ByVal (иначе сообщения о нелегальной операции не избежать). Чтобы обезопасить себя, можно сделать дополнительное специальное описание этой же функции для работы только со строковыми переменными:

Declare Function lreadString Lib “kernel32” _ Alias “_lread” (_ ByVal hFile As Long, ByVal lpBuffer As String, _ ByVal wBytes As Long) As Long

При работе с этим описанием указывать ByVal при обращении уже не нужно:

WBytes = lreadString (hFile&, MyVarString, _ Len(MyVarString)) ‘

Казалось бы, синтаксис оператора Declare позволяет сделать подобное специальное описание для массива:

Declare Function lreadString Lib “kernel32” Alias “_lread” (_ ByVal hFile As Long, lpBuffer() As Byte, _ ByVal wBytes As Long) As Long

Однако обращение

WBytes = lreadArray (hFile&, MyArray(), 10)

неизбежно приводит к фатальной ошибке программы.

Это продолжение разговора об особенностях обработки строковых переменных в Visual Basic: VB использует двухбайтную кодировку Unicode, Win API - однобайтную ANSI (причем с форматом, принятым в С, - с нулевым байтом в конце). Соответственно при использовании строковых переменных в качестве аргумента всегда автоматически производится преобразование из Unicode в ANSI при вызове API-функции (точнее, DLL-функции) и обратное преобразование при возврате.

Вывод из этого простой: с помощью переменных String можно обмениваться символьными данными, но нельзя использовать их для обмена произвольной двоичной информацией (как это было при работе с 16-разрядными версиями VB). В последнем случае лучше использовать одномерный байтовый массив.

Как известно, тип String можно использовать для описания пользовательской структуры. В связи с этим нужно помнить следующее:

  • Категорически нельзя использовать для обращения к Win API конструкцию следующего вида: Type MyStruct x As Single s As String ‘ строка переменной длины End Type

    В случае строки переменной длины в составе структуры передается дескриптор строки со всеми вытекающими отсюда последствиями в виде ошибки выполнения программы.

  • Можно использовать в качестве элемента структуры строку фиксированной длины: Type MyStruct x As Single s As String*8 ‘ строка фиксированной длины End Type

При этом производится соответствующее преобразование кодировок.

И последнее замечание: применять массив строковых переменных (как фиксированной, так и переменной длины) при обращении к API-функции нельзя ни в коем случае. Иначе появление «нелегальной операции» будет гарантировано.

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

Отметим в связи с этим, что смешанное программирование - это вполне обычное явление для реализации достаточно сложного приложения. Действительно, каждый язык (точнее, система программирования на базе языка) имеет свои сильные и слабые стороны, поэтому вполне логично использовать преимущества различных инструментов для решения разных задач. Например, VB - для создания пользовательского интерфейса, С - для эффективного доступа к системным ресурсам, Fortran - для реализации численных алгоритмов.

Мнение автора таково: сколь-нибудь серьезное занятие программированием требует от разработчика владения по крайней мере двумя инструментами. Разумеется, в современных условиях четкого разделения труда очень сложно быть отличным экспертом даже по двум системам, поэтому более логичной является схема «основной и вспомогательный языки». Идея здесь заключается в том, что даже поверхностное знание «вспомогательного» языка (написание довольно простых процедур) может очень заметно повысить эффективность применения «основного». Отметим, что знание VB хотя бы в качестве вспомогательного является сегодня практически обязательным требованием для профессионального программиста. Кстати, во времена DOS для любого программиста, в том числе Basic, было крайне желательным знание основ Ассемблера.

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

При изучении межпроцедурного интерфейса следует обратить внимание на следующие возможные «подводные камни»:

  • Разные языки могут использовать различные соглашения о правилах написания идентификаторов. Например, часто используется знак подчеркивания в начале имени процедуры, что запрещено в VB. Эта проблема легко решается с помощью ключевого слова Alias в операторе Declare (см. пример совета 2.3).
  • Может быть использована разная последовательность записи передаваемых аргументов в стек. Например, во времена DOS (честно признаюсь - не знаю, как это выглядит сейчас в среде Windows), C записывал аргументы с конца списка, другие языки (Fortran, Pascal, Basic) - с начала.
  • По умолчанию используются разные принципы передачи параметров - по ссылке или по значению.
  • Различные принципы хранения строковых переменных. Например, в C (так же как в Fortran и Pascal) длина строки определяется нулевым байтом в ее конце, а в Basic длина записывается в явном виде в дескрипторе строки. Разумеется, нужно иметь в виду возможность использования разных кодировок символов.
  • При передаче многомерных массивов следует помнить, что возможны различные варианты преобразования многомерных структур в одномерные (начиная с первого индекса или с последнего, применительно к двухмерным массивам - «по строчкам» или «по столбцам»).

С учетом всего этого можно сформулировать следующие рекомендации:

  • Используйте самые простые, проверенные способы передачи аргументов в DLL-функции. Стандарты, принятые для Win API, вполне годятся в качестве образца.
  • Ни в коем случае не передавайте массивы строковых переменных.
  • Очень внимательно используйте передачу простых строковых переменных и многомерных массивов.
  • Обязательно специальным образом проверяйте работоспособность механизма передачи аргументов в вызываемую процедуру и обратно. Напишите специальный тест для проверки передачи данных. Отдельно проверьте правильность передачи каждого аргумента. Например, если у вас есть процедура с несколькими аргументами, проверьте сначала корректность передачи каждого параметра для варианта с одним аргументом, а уж потом - для всего списка.

А что делать, если DLL-функция уже написана, например, на Фортране, но ее входной интерфейс не очень хорошо вписывается в приведенные выше стандарты VB? Здесь можно дать два совета. Первый: напишите тестовую DLL-функцию и с ее помощью постарайтесь методом проб и ошибок подобрать нужное обращение из VB-программы. Второй: напишите процедуру-переходник на том же Фортране, который бы обеспечивал простой интерфейс между VB и DLL-функцией с преобразованием простых структур данных в сложные (например, преобразовывал многомерный байтовый массив в строковый массив).

Итак: используйте DLL-функции. Но сохраняйте бдительность...

КомпьютерПресс 9"2000

Русский справочник по Win32 API

От изготовителя fb2.

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

Давайте, протестируем вашу читалку.

Если, вместо симпатичной таблицы вы увидели такое:

1 строка, 1 столбец

1 строка, 2 столбец

1 строка, 3 столбец

2 строка 1 столбец

2 строка 2 столбец

Значит ваша читалка таблиц не видит, что очень жаль, т.к. в книге их 49.

Что делать?... Ну, я поступаю так. В Mozilla Firefox поставил плагин для чтения fb2, и все проблемы решены, конечно, возможны и другие варианты...

Вот и все.

Успехов w_cat.

Из книги Журнал «Компьютерра» № 24 от 27 июня 2006 года автора Журнал «Компьютерра»

ОГОРОД КОЗЛОВСКОГО: Русский акцент Автор: Козловский ЕвгенийЭтот «Огород» - чисто публицистический. Без какого бы то ни было касательства к новинкам hi-tech. Впрочем, именно одна из таких новинок спровоцировала издевательскую катавасию, которую я намерен здесь описать, -

Из книги Microsoft Office автора Леонтьев Виталий Петрович

«РУССКИЙ ОФИС» – ПОЛЕЗНЫЕ ДОПОЛНЕНИЯ …Как известно, абсолютно идеального комплекта программ в природе не существует. И как бы ни был талантлив и мастеровит Microsoft Office, он умеет далеко не все. Но, к нашему счастью, этот пакет программ отличается не только умом и

Из книги Язык программирования С# 2005 и платформа.NET 2.0. автора Троелсен Эндрю

Подход C/Win32 API Традиционно разработка программного обеспечения для операционных систем семейства Windows предполагает использование языка программирования C в сочетании с Windows API (Application Programming Interface – интерфейс программирования приложений). Несмотря на тот факт, что в

Из книги Журнал PC Magazine/RE №08/2009 автора Журнал «PC Magazine»

Заголовок Win32 Заголовок Win32 декларирует, что компоновочный блок может загружаться и управляться средствами операционных систем семейства Windows. Данные этого заголовка также идентифицируют тип приложения (консольное, с графическим интерфейсом или библиотека

Из книги Цифровой журнал «Компьютерра» № 26 автора Журнал «Компьютерра»

Выполнение традиционных процессов Win32 Понятие "процесс" существовало в операционных системах Windows задолго до появления платформы.NET. Упрощенно говоря, термин процесс используется для обозначения множества ресурсов (таких, как внешние библиотеки программного кода и

Из книги Ощупывая слона [Заметки по истории русского Интернета] автора Кузнецов Сергей Юрьевич

Русский Android Компания «Вобис» выпускает коммуникатор на базе Google Android. Модель Highscreen PP5420 построена на процессоре Qualcomm MSM7201А (528 МГц), оснащена 128-Мбайт ОЗУ, 256-Мбайт ПЗУ, 3-дюйм сенсорным экраном с разрешением 240?400, GPS, датчиком пространственных перемещений G-Sensor – все вполне в

Из книги 10 простых и легких способов моментального повышения прибыльности любого коммерческого сайта автора Дин Терри

Вирус Win32/Stuxnet: заплат для Windows XP не будет Игорь Осколков Опубликовано 20 июля 2010 года На днях корпорация Microsoft подтвердила наличие уязвимости «нулевого дня» во всех версиях Windows - от 2000 до 7. Причём уязвимость оказалась очень необычной. Началось всего

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Александр Матросов (ESET) о вирусе Win32/Stuxnet Крестников Евгений Опубликовано 21 июля 2010 года Вирус Win32/Stuxnet интересен, прежде всего, своим механизмом распространения, использующим уязвимость в операционных системах Windows: специально сформированный

Из книги Технология XSLT автора Валиков Алексей Николаевич

Из книги Ководство автора Лебедев Артём Андреевич

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

ГЛАВА 1 Знакомство с Win32 и Win64 В этой главе вы познакомитесь с семейством операционных систем (ОС) Microsoft Windows и интерфейсом прикладного программирования (Application Programming Interface, API), который используется всеми членами этого семейства. Здесь также кратко описывается новейший

Из книги Виртуальная библиотека Delphi автора

Архитектура системы управления памятью в Win32 и Win64 Win32 (в данном случае различия между Win32 и Win64 становятся существенными) - это API 32-разрядных ОС семейства Windows. "32-разрядность" проявляет себя при адресации памяти тем, что указатели (LPSTR, LPDWORD и так далее) являются 4-байтовыми

Из книги автора

Переводы стандартов на русский язык? http://www.rol.ru/news/it/helpdesk/xml01.htmРасширяемый язык разметки (XML) 1.0 (вторая редакция). Перевод Радика Усманова, Luxoft (IBS).? http://www.rol.ru/news/it/helpdesk/xslt01.htmЯзык преобразований XSL (XSLT). Версия 1.0. Перевод Радика Усманова, Luxoft

Из книги автора

Из книги автора

О научном редакторе перевода на русский язык Кузьменко Дмитрий занимается проектированием и разработкой приложений баз данных уже 16 лет. С InterBase начал работать в 1994 году. В 2002 году Дмитрий основал фирму iBase (www.ibase.ru), которая занимается техническим сопровождением InterBase и

Из книги автора

Программирование на основе Win32 API в Delphi 1. Введение Любую современную программу или программную технологию можно представить как совокупность программных "слоев". Каждый из этих слоев производит свою собственную работу, которая заключается в повышении уровня абстракции

Интерфейс прикладного программирования WindowsAPI (applicationprogramminginterface) является интерфейсом системного программирования в пользовательском режиме для семейства операционных систем Windows. До выхода 64-разрядных версий Windows программный интерфейс для 32-разрядных версий операционных систем Windows назывался Win32 API, чтобы его можно было отличить от исходной 16-разрядной версии Windows API (которая служила интерфейсом программирования для начальных 16-разрядных версий Windows).

Windows API состоит из нескольких тысяч вызываемых функций, которые разбиты на следующие основные категории:

  • Базовыеслужбы (Base Services).
  • Службыкомпонентов (Component Services).
  • Службы пользовательского интерфейса (User Interface Services).
  • Графические и мультимедийные службы (Graphics and Multimedia Services).
  • Обмен сообщениями и совместная работа (Messaging and Collaboration).
  • Сеть (Networking).
  • Веб-службы (Web Services).

Описание WindowsAPI можно найти в документации по набору инструментальных средств разработки программного обеспечения - WindowsSoftwareDevelopmentKit (SDK). Эта документация доступна на веб-сайте www.msdn.microsoft.com. Она также включена со всеми уровнями подписки в сеть MicrosoftDeveloperNetwork (MSDN), предназначенную для разработчиков.

Microsoft .NET Framework состоит из библиотеки классов под названием Framework Class Library (FCL) и управляемой среды выполнения кода -Common Language Runtime (CLR). CLR обладает функциями своевременной компиляции, проверки типов, сборки мусора и обеспечения безопасности доступа к коду. Предлагая эти функции, CLR предоставляет среду разработки, повышающую производительность работы программистов и сокращающую количество наиболее распространенных ошибок программирования.

Среда CLR реализована, как классический COM-сервер, код которого находится в стандартной Windows DLL-библиотеке, предназначенной для работы в пользовательском режиме. Фактически все компоненты.NET Framework реализованы как стандартные Windows DLL-библиотеки пользовательского режима, наложенные поверх неуправляемых функций Windows API. (Ни один из компонентов.NET Framework не работает в режиме ядра.) Взаимоотношения между этими компонентами показаны на рисунке.

Службы, функции и стандартные программы.

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

  • Функции Windows API . Документированные, вызываемые подпрограммы в WindowsAPI. Например, CreateProcess, CreateFile и GetMessage.
  • Собственные системные службы (или системные вызовы) . Недокументированные базовые службы в операционной системе, вызываемые при работе в пользовательском режиме. Например, NtCreateUserProcess является внутренней службой, которую функция Windows CreateProcess вызывает для создания нового процесса.
  • Функции поддержки ядра (или подпрограммы) . Подпрограммы внутри операционной системы Windows, которые могут быть вызваны только из режима ядра. Например, ExAllocatePoolWithTag является подпрограммой, вызываемой драйверами устройств для выделения памяти из системных динамически распределяемых областей Windows (называемых пулами).
  • Службы Windows. Процессы, запускаемые Диспетчером управления службами (Windowsservicecontrolmanager). Например, служба Диспетчер задач запускается в виде процесса, работающего в пользовательском режиме, в котором поддерживается команда at (аналогичная UNIX-командам at или cron).
  • Библиотеки DLL (dynamic-link libraries - динамически подключаемые библиотеки) . Набор вызываемых подпрограмм, связанных вместе в виде двоичного файла, который может быть загружен в динамическом режиме приложениями, которые используют эти подпрограммы. В качестве примера можно привести Msvcrt.dll (библиотеку времени выполнения для приложений, написанных на языке C) и Kernel32.dll (одну из библиотек подсистемы Windows API). DLL-библиотеки широко используются компонентами и приложениями Windows, которые работают в пользовательском режиме. Преимущество, предоставляемое DLL-библиотеками по сравнению со статическими библиотеками, заключается в том, что они могут использоваться сразу несколькими приложениями, и Windows обеспечивает наличие в памяти только одной копии кода DLL-библиотеки для тех приложений, в которых имеются ссылки на эту библиотеку. Следует заметить, что неисполняемые.NET-сборки компилируются как DLL-библиотеки, но без каких-либо экспортируемых подпрограмм. CLR анализирует скомпилированные метаданные для доступа к соответствующим типам и элементам классов.

История Win32 API.

Интересно, что Win32 не планировался в качестве исходного интерфейса программирования для той системы, которая в ту пору называлась Windows NT. Поскольку проект Windows NT запускался в качестве замены для OS/2 версии 2, первоначальным интерфейсом программирования был 32-разрядный OS/2 PresentationManagerAPI. Но через год после запуска проекта произошел взлет поступившей в продажу Microsoft Windows 3.0. В результате этого Microsoft сменила направление и сделала Windows NT будущей заменой семейства продуктов Windows, а не заменой OS/2. В связи с этим и возникла необходимость выработать спецификацию Windows API - до этого, в Windows 3.0, API существовал только в виде 16-разрядного интерфейса.

Хотя в Windows API намечалось введение множества новых функций, недоступных в Windows 3.1, Microsoft решила сделать новый API, по возможности, максимально совместимым по именам, семантике и используемым типам данных с 16-разрядным Windows API, чтобы облегчить бремя переноса существующих 16-разрядных Windows-приложений в Windows NT. Этим, собственно, и объясняется тот факт, что многие имена функций и интерфейсов могут показаться непоследовательными: так нужно было для обеспечения совместимости нового Windows API со старым 16-разрядным Windows API.