Работа службы Platform Invoke. Запуск функций WinAPI
Наиболее часто служба Platform Invoke применяется для запуска функций WinAPI, находящихся в файлах dll. Когда служба вызывает функцию, совершаются следующие операции:
- обнаружение необходимой библиотеки;
- загрузка найденной библиотеки в оперативную память;
- обнаружение адреса библиотеки в памяти и передача аргументов функции, с их преобразованием при необходимости;
- после этого Platform Invoke передает управление неуправляемой функции и ждет завершения.
Для подключения функции необходимо представить адрес библиотеки и данные о функции: название, входящие и исходящие аргументы.
Windows API — это набор функций, входящий в состав семейства операционной системы Microsoft Windows. Преимуществом использования этих функций является то, что они уже полностью готовы и не приходится тратить время на реализацию подобной функциональности. Однако с ними тяжело работать — в частности, довольно сложно отлавливать исключения, возникающие в работе приложения.
Первым шагом в запуске неуправляемой функции является объявление функции. Функция должна быть статической (static) и внешней (extern). Далее следует импорт библиотеки, содержащей эту функцию. Импортировать библиотеку нужно, используя атрибут DllImport, который находится в пространстве имен System.Runtime.InteropServices. Атрибут DllImport нуждается в названии библиотеки и может принимать один из параметров, указанных в таблице 5.2:
EntryPoint | Указывает название функции. Если название метода совпадает с названием неуправляемой функции, то этот аргумент ставить необязательно |
CharSet | Указывает кодировку строковых значений. Значением по умолчанию является ANSI |
ExactSpelling | Предотвращает изменение точки входа (entry point) при изменении кодировки. Если значение аргумента CharSet установлено в Auto, то значение по умолчанию — true, в противном случае — false |
CallingConvention | Указывает тип конвертирования аргументов, передаваемых в функцию. Значением по умолчанию является WinAPI |
PreserveSig | Указывает, что сигнатура управляемого метода не должна трансформироваться в сигнатуру неуправляемого метода, который возвращает значение типа HRESULT и может иметь дополнительные аргументы в качестве возвращаемых значений Значением по умолчанию является true (сигнатура не должна трансформироваться). |
SetLastError | Указывает возможность использования метода GetLastError для обработки ошибок при выполнении неуправляемого метода. Значением по умолчанию является false |
Наиболее часто служба Platform Invoke применяется для запуска функций WinAPI, находящихся в файлах dll. Когда служба вызывает функцию, совершаются следующие операции:
- обнаружение необходимой библиотеки;
- загрузка найденной библиотеки в оперативную память;
- обнаружение адреса библиотеки в памяти и передача аргументов функции, с их преобразованием при необходимости;
- после этого Platform Invoke передает управление неуправляемой функции и ждет завершения.
Для подключения функции необходимо представить адрес библиотеки и данные о функции: название, входящие и исходящие аргументы.
Windows API — это набор функций, входящий в состав семейства операционной системы Microsoft Windows. Преимуществом использования этих функций является то, что они уже полностью готовы и не приходится тратить время на реализацию подобной функциональности. Однако с ними тяжело работать — в частности, довольно сложно отлавливать исключения, возникающие в работе приложения.
Первым шагом в запуске неуправляемой функции является объявление функции. Функция должна быть статической (static) и внешней (extern). Далее следует импорт библиотеки, содержащей эту функцию. Импортировать библиотеку нужно, используя атрибут DllImport, который находится в пространстве имен System.Runtime.InteropServices. Атрибут DllImport нуждается в названии библиотеки и может принимать один из параметров, указанных в таблице 5.2:
EntryPoint | Указывает название функции. Если название метода совпадает с названием неуправляемой функции, то этот аргумент ставить необязательно |
CharSet | Указывает кодировку строковых значений. Значением по умолчанию является ANSI |
ExactSpelling | Предотвращает изменение точки входа (entry point) при изменении кодировки. Если значение аргумента CharSet установлено в Auto, то значение по умолчанию — true, в противном случае — false |
CallingConvention | Указывает тип конвертирования аргументов, передаваемых в функцию. Значением по умолчанию является WinAPI |
PreserveSig | Указывает, что сигнатура управляемого метода не должна трансформироваться в сигнатуру неуправляемого метода, который возвращает значение типа HRESULT и может иметь дополнительные аргументы в качестве возвращаемых значений Значением по умолчанию является true (сигнатура не должна трансформироваться). |
SetLastError | Указывает возможность использования метода GetLastError для обработки ошибок при выполнении неуправляемого метода. Значением по умолчанию является false |
Аргументы, которые принадлежат к простым типам данных, такие как byte или int, Platform Invoke автоматически преобразовывает в соответствующие типы в неуправляемой платформе. В таблице 5.3 приводится соответствие типов данных в функциях WinAPI и библиотеки .NET Framework.
HANDLE | Int |
BYTE | Byte |
SHORT | Short |
WORD | Ushort |
INT | Int |
UINT | Uint |
LONG | Int |
ULONG | Uint |
BOOLEAN | Int |
CHAR | Char |
LPSTR (и большинство строковых типов данных) | String для входящих аргументов, StringBuilder для двусторонних аргументов |
FLOAT | Float |
DOUBLE | double |
Аргументы, которые принадлежат к простым типам данных, такие как byte или int, Platform Invoke автоматически преобразовывает в соответствующие типы в неуправляемой платформе. В таблице 5.3 приводится соответствие типов данных в функциях WinAPI и библиотеки .NET Framework.
HANDLE | Int |
BYTE | Byte |
SHORT | Short |
WORD | Ushort |
INT | Int |
UINT | Uint |
LONG | Int |
ULONG | Uint |
BOOLEAN | Int |
CHAR | Char |
LPSTR (и большинство строковых типов данных) | String для входящих аргументов, StringBuilder для двусторонних аргументов |
FLOAT | Float |
DOUBLE | double |
При указании библиотеки не нужно указывать путь до нее. CLR ищет библиотеку в каталоге приложения, затем в подкаталогах, в папке Windows и папке Window\System32. При указании адреса библиотеки могут возникнуть исключения — CLR проверяет только его. Например, если был указан адрес "C:\Windos\system32\someDll.dl", а у пользователя операционная система располагается на диске D — приложение работать не будет. При использовании функций WinAPI сами файлы библиотек не нужно включать в проект.