iOS와 유사한 플랫폼에 대한 사용자 지정 프레임워크 만들기 및 사용
.NET 9부터 Native AOT는 iOS와 유사한 플랫폼용 iOS 워크로드에 의존하지 않는 .NET 클래스 라이브러리 게시를 지원합니다. 이 지원을 통해 iOS, Mac Catalyst 및 tvOS 애플리케이션에서 사용할 수 있는 자체 포함 네이티브 라이브러리를 만들 수 있습니다.
Important
이 방법은 기본 제공 Objective-C 상호 운용성 지원과 함께 제공되지 않으며 상호 운용성을 달성하기 위해 추가 코드 적응(예: 참조 형식 인수 마샬링)이 필요할 수 있습니다.
공유 라이브러리 빌드
이 섹션에서는 NativeAOT를 지원하는 간단한 .NET 클래스 라이브러리 프로젝트를 만들고 iOS와 유사한 플랫폼용 네이티브 라이브러리를 생성하는 단계를 설명합니다.
.NET 9 SDK 다운로드
클래스 라이브러리 프로젝트 만들기
dotnet new classlib -n "MyNativeAOTLibrary"
프로젝트 파일에 다음 속성을 추가합니다.
MyNativeAOTLibrary.csproj
<PublishAot>true</PublishAot> <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
MyNativeAOTLibrary/Class1.cs
소스 코드를 편집하여 네이티브 코드aotsample_add
에서 참조할 수 있도록 관리되는 메서드를 노출합니다. 예시:using System.Runtime.InteropServices; namespace NaotLib; public class Class1 { [UnmanagedCallersOnly(EntryPoint = "aotsample_add")] public static int Add(int a, int b) { return a + b; } }
클래스 라이브러리를 게시하고 적절한 런타임 식별자를 지정하여 원하는 iOS와 유사한 플랫폼을 대상으로 지정합니다(아래 참조
<rid>
).dotnet publish -r <rid> MyNativeAOTLibrary/MyNativeAOTLibrary.csproj
이전 단계를 성공적으로 완료하면 다음 위치에 있는 MyNativeAOTLibrary/bin/Release/net9.0/<rid>/publish/
공유 라이브러리 MyNativeAOTLibrary.dylib
및 해당 디버그 기호MyNativeAOTLibrary.dylib.dSYM
와 같은 파일 쌍이 생성됩니다.
참고 항목
유니버설 프레임워크를 만들려면 지정된 플랫폼에 대한 아키텍처와 x64
둘 다 Arm64
에 대한 클래스 라이브러리를 게시해야 합니다.
즉, 다른 런타임 식별자를 사용하여 5단계를 반복해야 합니다.
예를 들어 공유 라이브러리를 사용자 지정 MacCatalyst 유니버설 프레임워크에 패키징하기 위한 필수 조건으로 런타임 식별자와 함께 maccatalyst-arm64
maccatalyst-x64
클래스 라이브러리를 게시합니다.
사용자 지정 프레임워크 만들기 및 사용
Apple은 애플리케이션에서 사용하려면 공유 라이브러리(.dylibs)를 프레임워크로 패키지해야 한다는 요구 사항을 적용합니다.
이 섹션에서는 이를 위해 필요한 모든 단계와 공유 NativeAOT 라이브러리/프레임워크를 사용하는 iOS/MacCatalyst 애플리케이션의 간단한 시나리오에 대해 설명합니다.
참고 항목
설명된 단계는 데모용입니다. 실제 요구 사항은 정확한 사용 사례에 따라 다를 수 있습니다.
공유 라이브러리를 사용자 지정 iOS 프레임워크에 패키지
프레임워크 폴더 만들기:
mkdir MyNativeAOTLibrary.framework
부하 명령 조정:
LC_RPATH
load 명령install_name_tool -rpath @executable_path @executable_path/Frameworks MyNativeAOTLibrary/bin/Release/net9.0/ios-arm64/publish/MyNativeAOTLibrary.dylib
LC_ID_DYLIB
load 명령install_name_tool -id @rpath/MyNativeAOTLibrary.framework/MyNativeAOTLibrary MyNativeAOTLibrary/bin/Release/net9.0/ios-arm64/publish/MyNativeAOTLibrary.dylib
이진 파일을 범용 파일로 수동으로 패키지합니다.
lipo -create MyNativeAOTLibrary/bin/Release/net9.0/ios-arm64/publish/MyNativeAOTLibrary.dylib -output MyNativeAOTLibrary.framework/MyNativeAOTLibrary
프레임워크에 속성 목록 파일을 추가합니다.
Info.plist
파일을 만듭니다.
touch MyNativeAOTLibrary.framework/Info.plist
- 부록의 내용을 만든
Info.plist
파일에 추가합니다.
마지막 단계가 끝나면 프레임워크 구조는 다음과 같이 표시됩니다.
MyNativeAOTLibrary.framework
|_ MyNativeAOTLibrary
|_ Info.plist
공유 라이브러리를 사용자 지정 MacCatalyst 유니버설 프레임워크로 패키지
유니버설 프레임워크에는 아키텍처 모두 Arm64
x64
에 대한 이진 파일이 필요합니다.
이러한 이유로 다음 RID를 모두 대상으로 하는 네이티브 라이브러리를 미리 maccatalyst-arm64
maccatalyst-x64
게시해야 합니다.
프레임워크 폴더 구조를 만듭니다.
mkdir -p MyNativeAOTLibrary.framework/Versions/A/Resources ln -sfh Versions/Current/MyNativeAOTLibrary MyNativeAOTLibrary.framework/MyNativeAOTLibrary ln -sfh Versions/Current/Resources MyNativeAOTLibrary.framework/Resources ln -sfh A MyNativeAOTLibrary.framework/Versions/Current
부하 명령 조정:
LC_RPATH
load 명령install_name_tool -rpath @executable_path @executable_path/../Frameworks MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-arm64/publish/MyNativeAOTLibrary.dylib install_name_tool -rpath @executable_path @executable_path/../Frameworks MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-x64/publish/MyNativeAOTLibrary.dylib
LC_ID_DYLIB
load 명령install_name_tool -id @rpath/MyNativeAOTLibrary.framework/Versions/A/MyNativeAOTLibrary MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-arm64/publish/MyNativeAOTLibrary.dylib install_name_tool -id @rpath/MyNativeAOTLibrary.framework/Versions/A/MyNativeAOTLibrary MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-x64/publish/MyNativeAOTLibrary.dylib
이진 파일을 범용 파일로 수동으로 패키지합니다.
lipo -create MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-arm64/publish/MyNativeAOTLibrary.dylib MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-x64/publish/MyNativeAOTLibrary.dylib -output MyNativeAOTLibrary.framework/Versions/A/MyNativeAOTLibrary
프레임워크에 속성 목록 파일을 추가합니다.
Info.plist
파일을 만듭니다.
touch MyNativeAOTLibrary.framework/Versions/A/Resources/Info.plist
- 부록의 내용을 만든
Info.plist
파일에 추가합니다.
마지막 단계가 끝나면 프레임워크 구조는 다음과 같이 표시됩니다.
MyNativeAOTLibrary.framework
|_ MyNativeAOTLibrary -> Versions/Current/MyNativeAOTLibrary
|_ Resources -> Versions/Current/Resources
|_ Versions
|_ A
| |_ Resources
| | |_ Info.plist
| |_ MyNativeAOTLibrary
|_ Current -> A
사용자 지정 프레임워크 사용
열기
Xcode
(이 예제Xcode 16.0
에서는 사용됨)새
App
프로젝트 만들기앱의 이름(예
MyiOSApp
: )을 선택하고 원본 언어로 Objective-C를 선택합니다.프레임워크에 대한 참조
MyNativeAOTLibrary
추가- 대상 일반 탭의
MyiOSApp
프레임워크, 라이브러리 및 포함된 콘텐츠 아래에서 참조된 프레임워크로 추가MyNativeAOTLibrary
하려면 선택합니다+. - 대화 상자에서 기타 추가 ->파일 추가를 선택한 다음 위치로 이동하여
MyNativeAOTLibrary.framework
선택합니다. - 선택한 후 프레임워크에 대한 옵션을 설정합니다
Embed and Sign
.MyNativeAOTLibrary
- 대상 일반 탭의
빌드 설정 탭의 프레임워크 검색 경로 목록에 위치 추가
MyNativeAOTLibrary.framework
노출된 관리 메서드
aotsample_add
를 호출하고 결과를 인쇄하여 편집main.m
extern int aotsample_add(int a, int b); int main(int argc, char * argv[]) { ... NSLog(@"2 + 5 = %d", aotsample_add(2, 5)); ... }
실제 iOS 디바이스를 선택하고 앱을 빌드/실행합니다.
앱이 성공적으로 시작된 후 로그를 검사합니다. 앱은 다음을 출력해야 합니다.
2 + 5 = 7
참고 항목
MacCatalyst의 경우 실행 대상을 다음과 같이 Mac (Mac Catalyst)
설정해야 하는 7단계를 제외하고 동일한 단계를 사용합니다.
iOS와 유사한 플랫폼용 NativeAOT를 사용하여 정적 라이브러리 빌드
네이티브 라이브러리 빌드 개요에 설명된 대로 몇 가지 제한 사항으로 인해 정적 라이브러리보다 공유 라이브러리를 빌드하는 것이 좋습니다.
그러나 원하는 경우 공유 라이브러리를 빌드하는 단계에 따라 프로젝트 파일에 추가 속성을 포함하여 정적 라이브러리를 빌드할 수 있습니다.
<NativeLib>Static</NativeLib>
프로젝트가 게시된 후 정적 라이브러리 MyNativeAOTLibrary.a
는 다음 위치에서 MyNativeAOTLibrary/bin/Release/net9.0/<rid>/publish
찾을 수 있습니다.
이 문서에서는 정적 라이브러리를 사용하고 소비자 프로젝트를 구성하는 방법을 다루지 않습니다.
부록 Info.plist 콘텐츠
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>MyNativeAOTLibrary</string>
<key>CFBundleIdentifier</key>
<string>com.companyname.MyNativeAOTLibrary</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleExecutable</key>
<string>MyNativeAOTLibrary</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
</dict>
</plist>
.NET