Создание Windows-приложений на основе Visual C#

         

Работа службы Platform Invoke. Запуск функций WinAPI


Наиболее часто служба Platform Invoke применяется для запуска функций WinAPI, находящихся в файлах dll. Когда служба вызывает функцию, совершаются следующие операции:

  • обнаружение необходимой библиотеки;
  • загрузка найденной библиотеки в оперативную память;
  • обнаружение адреса библиотеки в памяти и передача аргументов функции, с их преобразованием при необходимости;
  • после этого Platform Invoke передает управление неуправляемой функции и ждет завершения.

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

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

Первым шагом в запуске неуправляемой функции является объявление функции. Функция должна быть статической (static) и внешней (extern). Далее следует импорт библиотеки, содержащей эту функцию. Импортировать библиотеку нужно, используя атрибут DllImport, который находится в пространстве имен System.Runtime.InteropServices. Атрибут DllImport нуждается в названии библиотеки и может принимать один из параметров, указанных в таблице 5.2:

Таблица 5.2. Некоторые параметры атрибута DllImport

АргументОписание
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:

Таблица 5.2. Некоторые параметры атрибута DllImport

АргументОписание
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.

Таблица 5.3. Тип данных в неуправляемом кодеТип данных в .NET Framework (C#)
HANDLEInt
BYTEByte
SHORTShort
WORDUshort
INTInt
UINTUint
LONGInt
ULONGUint
BOOLEANInt
CHARChar
LPSTR (и большинство строковых типов данных)String для входящих аргументов, StringBuilder для двусторонних аргументов
FLOATFloat
DOUBLEdouble
При указании библиотеки не нужно указывать путь до нее. CLR ищет библиотеку в каталоге приложения, затем в подкаталогах, в папке Windows и папке Window\System32. При указании адреса библиотеки могут возникнуть исключения — CLR проверяет только его. Например, если был указан адрес "C:\Windos\system32\someDll.dl", а у пользователя операционная система располагается на диске D — приложение работать не будет. При использовании функций WinAPI сами файлы библиотек не нужно включать в проект.


Аргументы, которые принадлежат к простым типам данных, такие как byte или int, Platform Invoke автоматически преобразовывает в соответствующие типы в неуправляемой платформе. В таблице 5.3 приводится соответствие типов данных в функциях WinAPI и библиотеки .NET Framework.



Таблица 5.3. Тип данных в неуправляемом кодеТип данных в .NET Framework (C#)
HANDLEInt
BYTEByte
SHORTShort
WORDUshort
INTInt
UINTUint
LONGInt
ULONGUint
BOOLEANInt
CHARChar
LPSTR (и большинство строковых типов данных)String для входящих аргументов, StringBuilder для двусторонних аргументов
FLOATFloat
DOUBLEdouble


При указании библиотеки не нужно указывать путь до нее. CLR ищет библиотеку в каталоге приложения, затем в подкаталогах, в папке Windows и папке Window\System32. При указании адреса библиотеки могут возникнуть исключения — CLR проверяет только его. Например, если был указан адрес "C:\Windos\system32\someDll.dl", а у пользователя операционная система располагается на диске D — приложение работать не будет. При использовании функций WinAPI сами файлы библиотек не нужно включать в проект.


Содержание раздела