Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Нативная интероперация — это технология, которая позволяет получать доступ к неуправляемым библиотекам из управляемого кода или делать управляемые библиотеки доступными для неуправляемого кода (в противоположном направлении).
Хотя взаимодействие с нативным кодом работает аналогично в развертываниях Native AOT и без AOT, существуют некоторые особенности, которые отличаются при публикации в качестве Native AOT.
Прямые вызовы P/Invoke
Вызовы P/Invoke в двоичных файлах, скомпилированных AOT, по умолчанию привязаны неявно во время выполнения для повышения совместимости. Компилятор AOT можно настроить для создания прямых вызовов выбранных методов P/Invoke, привязанных во время запуска динамическим загрузчиком, который поставляется с операционной системой. Неуправляемые библиотеки и точки входа, на которые ссылаются прямые вызовы, всегда должны быть доступны во время выполнения, в противном случае собственный двоичный файл не запускается.
Преимущества прямых вызовов P/Invoke:
- Они имеют лучшую стационарную производительность.
- Они позволяют связать неуправляемые зависимости статически.
Вы можете настроить генерацию прямого вызова P/Invoke с помощью <DirectPInvoke> объектов в файле проекта. Имя элемента может быть либо <modulename>, что позволяет прямые вызовы для всех точек входа в модуле, либо <modulename!entrypointname>, что обеспечивает прямой вызов только для конкретного модуля и точки входа.
Чтобы указать список точек входа во внешнем файле, используйте <DirectPInvokeList> элементы в файле проекта. Список полезен, если количество прямых вызовов P/Invoke большое, и это непрактично указывать их с помощью отдельных <DirectPInvoke> элементов. Файл может содержать пустые строки и комментарии, начиная с #.
Примеры.
<ItemGroup>
<!-- Generate direct PInvoke calls for everything in __Internal -->
<!-- This option replicates Mono AOT behavior that generates direct PInvoke calls for __Internal -->
<DirectPInvoke Include="__Internal" />
<!-- Generate direct PInvoke calls for everything in libc (also matches libc.so on Linux or libc.dylib on macOS) -->
<DirectPInvoke Include="libc" />
<!-- Generate direct PInvoke calls for Sleep in kernel32 (also matches kernel32.dll on Windows) -->
<DirectPInvoke Include="kernel32!Sleep" />
<!-- Generate direct PInvoke for all APIs listed in DirectXAPIs.txt -->
<DirectPInvokeList Include="DirectXAPIs.txt" />
</ItemGroup>
В Windows Native AOT использует предварительно заполненный список прямых методов P/Invoke, доступных во всех поддерживаемых версиях Windows.
Предупреждение
Поскольку прямые методы P/Invoke разрешаются динамическим загрузчиком операционной системы, а не библиотекой среды выполнения Native AOT, прямые методы P/Invoke не будут учитывать DefaultDllImportSearchPathsAttribute. Порядок поиска библиотек будет соответствовать правилам динамического загрузчика, определенным операционной системой. Некоторые операционные системы и загрузчики предлагают способы управления динамической загрузкой с помощью флагов компоновщика (например: /DEPENDENTLOADFLAG на Windows или -rpath в Linux). Дополнительные сведения об указании флагов компоновщика см. в разделе Связывание.
Связывание
Чтобы статически связаться с неуправляемой библиотекой, необходимо указать <NativeLibrary Include="filename" /> , указывая .lib на файл в Windows и .a файл в системах, таких как Unix.
Примеры.
<ItemGroup>
<!-- Generate direct PInvokes for Dependency -->
<DirectPInvoke Include="Dependency" />
<!-- Specify library to link against -->
<NativeLibrary Include="Dependency.lib" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
<NativeLibrary Include="Dependency.a" Condition="!$(RuntimeIdentifier.StartsWith('win'))" />
</ItemGroup>
Чтобы указать дополнительные флаги для родного компоновщика, используйте <LinkerArg> элемент.
Примеры.
<ItemGroup>
<!-- link.exe is used as the linker on Windows -->
<LinkerArg Include="/DEPENDENTLOADFLAG:0x800" Condition="$(RuntimeIdentifier.StartsWith('win'))" />
<!-- Native AOT invokes clang/gcc as the linker, so arguments need to be prefixed with "-Wl," -->
<LinkerArg Include="-Wl,-rpath,'/bin/'" Condition="$(RuntimeIdentifier.StartsWith('linux'))" />
</ItemGroup>
Собственные экспорты
Собственный компилятор AOT экспортирует методы, аннотированные с UnmanagedCallersOnlyAttribute и с непустым свойством EntryPoint в качестве общедоступных точек входа C. Это позволяет динамически или статически связывать скомпилированные модули AOT с внешними программами. Рассматриваются только методы, помеченные UnmanagedCallersOnly в опубликованной сборке. Методы в ссылках на проекты или пакетах NuGet не будут экспортированы.
Дополнительные сведения см. в примере NativeLibrary.