本文說明如何使用 Maui.NativeLibraryInterop 開始使用原生連結庫 Interop 來簡化設定。
這些指示概述透過原生連結庫 Interop 建立系結的基本步驟、關鍵決策點和指引範例。 如需特定 API 和實作詳細數據的進一步指引,請參閱相關原生 SDK 和連結庫的檔。
必要條件
安裝必要條件:
- .NET 9 SDK(軟體開發工具包)
-
.NET MAUI 工作負載 (透過 Visual Studio 或 CLI
dotnet workload install maui) - Android SDK
- Android Studio
-
Objective-Sharpie (用來手動產生 C# API)
- Xamarin.iOS (Objective-Sharpie 必須能夠運作)
- Visual Studio 或 Visual Studio Code
- Xcode
-
Xcode 命令列工具 (
xcode-select --install)
注意
可以獨立方式安裝 Android SDK 和/或 Xcode 命令行工具 。 不過,Xcode 命令行工具的安裝通常是透過 Xcode 來處理。 同樣地, Android SDK 安裝通常是透過 Android Studio 和 /或 .NET MAUI VS Code 擴充 功能,根據 .NET MAUI 用戶入門 文件來處理。
建立新的系結
若要開始建立新的系結,最簡單的方式是在Maui.NativeLibraryInterop存放庫中複製範本,並從該處進行修改。 若要進一步瞭解 Maui.NativeLibraryInterop 目前設定方式的完整範圍,請參閱概觀文件。
設定 .NET 系結連結庫
此 範本 包含適用於 Android 的入門 .NET 和適用於 iOS 系結連結庫的 .NET。
更新系結連結庫,以反映 .NET 應用程式中所需的目標平臺和 .NET 版本。
注意
例如:如果您的目標是只使用 .NET 9 建立 iOS 系結,您可以:
- 刪除範本/android/NewBinding.Android.Binding的 Android 系結連結庫,以及
- 更新 template/macios/NewBinding.MaciOS.Binding/NewBinding.MaciOS.Binding.maciOS.Binding.csproj 中的目標架構,以設定為
net9.0-ios。
設定原生包裝函式專案和連結庫
此 範本 也包含入門 Android Studio 專案和 Xcode 專案。
更新原生專案,以視需要在 .NET 應用程式中反映目標平臺和版本,並在下列步驟中包含感興趣的原生連結庫。
設定:iOS 和 Mac Catalyst
Xcode 項目位於 template/macios/native/NewBinding。
更新 Xcode 專案,以反映 .NET 應用程式中支援的目標平臺和版本。 在 Xcode 專案中,按兩下最上層架構,然後在 [目標一般] 中>:
- 視需要新增/移除任何 支援目的地 。
- 視需要調整 iOS 版本。
透過任何最適合您連結庫和需求的方法,將 iOS 和/或 MacCatalyst 的原生連結庫帶入您的 Xcode 專案(例如 CocoaPods、Swift 封裝管理員)。
安裝程式:Android
Android Studio 專案位於 template/android/native。
更新 Android Studio 專案,以反映 .NET 應用程式中支援的目標版本。
- 流覽至 build.gradle.kts (:app) 檔案
-
compileSdk視需要更新版本
透過 gradle 引進 Android 原生連結庫
- 在 build.gradle.kts (:app) 檔案的相依性區塊中新增套件相依性。
- 將存放庫新增至
dependencyResolutionManagementrepositoriessettings.gradle.kts 檔案中的 區塊。 - 將專案與 gradle 檔案同步處理(透過 Android Studio 右上角的按鈕)。
建立 API 介面
使用下列步驟,在原生專案與 .NET 系結項目之間建立 API 介面。
API 定義:iOS 和 Mac Catalyst
在原生端,在 template/macios/native/NewBinding/NewBinding/DotnetNewBinding.swift 中進行更新:
- 新增 import 語句以匯入您剛才新增的原生連結庫。
- 為感興趣的原生連結庫 API 撰寫 API 定義。
- 請確定 Xcode 專案建置成功,且您對 API 感到滿意。
回到 .NET 端,我們現在已準備好與原生連結庫進行互操作性:
-
dotnet build從 template/macios/NewBinding.MaciOS.Binding 執行,以測試所有專案都正確且正常運作。 - 使用 Objective Sharpie 生成 C# 系結以供 Swift API 更新:
- 流覽至 template/macios/NewBinding.MaciOS.Binding/bin/Debug/net9.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64/NewBinding.framework 在 MaciOS 系結項目輸出資料夾中。
- 執行
sharpie xcode -sdks,以取得系結命令的有效目標 SDK 值清單。 選取與你要在下一個指令中使用的平臺和版本相符合的值,例如iphoneos18.0。 - 針對系結專案所建立的 xcframework 中的標頭檔執行
sharpie bind:sharpie bind --output=sharpie-out --namespace=NewBindingMaciOS --sdk=iphoneos18.0 --scope=Headers Headers/NewBinding-Swift.h - 更新 template/macios/NewBinding.MaciOS.Binding/ApiDefinition.cs的內容,將其替換為 template/macios/NewBinding.MaciOS.Binding/bin/Debug/net9.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64/NewBinding.framework/sharpie-out/ApiDefinitions.cs的內容,並視需要進行調整(例如:命名)。
- 再次從
dotnet build執行。
另請參閱 objective-sharpie 文件,以瞭解更多有關此工具的資訊。
API 定義:Android
在原生端,在 範本/android/native/newbinding/src/main/java/com/example/newbinding/DotnetNewBinding.java中進行更新:
- 新增 import 語句以匯入您剛才新增的原生連結庫。
- 為感興趣的原生連結庫 API 撰寫 API 定義。
- 請確定 Android Studio 專案建置成功,且您滿意 API。
回到 .NET 端,我們現在已準備好與原生連結庫進行互操作性:
-
dotnet build從 template/android/NewBinding.Android.Binding 執行,以測試所有專案都已正確插入並正常運作。 (注意:此步驟會要求您安裝 JDK 17) - 藉由在本機 Android 專案中每個要綁定的 maven 相依項目,將
@(AndroidMavenLibrary)項目新增到 template/sample/MauiSample.csproj 來參考任何 Android 綁定相依性。 這會啟用專案的 Java 相依性驗證,並導致後續組建產生遺漏相依性的建置警告或錯誤。 您可以新增@(AndroidMavenLibrary)或@(PackageReference)元素,以滿足您所系結的原生程式庫的 Java 相依鏈結,從而解決這些警告/錯誤。 注意:Gradle/Maven 相依關係通常需要明確參考,因為它們不會自動納入到您的程式庫中。)
<ItemGroup Condition="$(TargetFramework.Contains('android'))">
<AndroidMavenLibrary Include="{DependencyGroupId}:{DependencyName}" Version="{DependencyVersion}" Bind="false" />
</ItemGroup>
如需了解此流程的更多資訊,另請參閱 AndroidMavenLibrary 參考 和 Java 相依性驗證 文檔。
注意
您可以重新命名佔位元元 DotnetNewBinding 類別,以更清楚地反映要包裝的原生連結庫。 如需撰寫 API 定義的更多範例和秘訣,請參閱下 一節:修改現有的系結。
在您的 .NET 應用程式中取用 API
此範本包含範本/範例/MauiSample 的 .NET MAUI 範例應用程式,其會參考 .NET 系結專案,並讓原生連結庫立即可供使用!
如果您有興趣使用自己的 .NET MAUI、適用於 Android 的 .NET、適用於 iOS 的 .NET 和/或 .NET for Mac Catalyst 應用程式,不過,您可以修改 .NET 應用程式專案檔來參考系結連結庫:.
<!-- Reference to MaciOS Binding project -->
<ItemGroup Condition="$(TargetFramework.Contains('ios')) Or $(TargetFramework.Contains('maccatalyst'))">
<ProjectReference Include="..\..\macios\NewBinding.MaciOS.Binding\NewBinding.MaciOS.Binding.csproj" />
</ItemGroup>
<!-- Reference to Android Binding project -->
<ItemGroup Condition="$(TargetFramework.Contains('android'))">
<ProjectReference Include="..\..\android\NewBinding.Android.Binding\NewBinding.Android.Binding.csproj" />
</ItemGroup>
修改現有的系結
如果現有的 API 介面未公開您自己專案中所需的功能,是時候進行自己的修改了!
iOS 和 Mac Catalyst
在 Xcode 專案中,您會發現一或多個 Swift 檔案,這些檔案會定義系結的公用 API 介面。 例如, register Firebase Messaging 的 方法定義為:
@objc(MauiFIRMessaging)
public class MauiFIRMessaging : NSObject {
@objc(register:completion:)
public static func register(apnsToken: NSData, completion: @escaping (String?, NSError?) -> Void) {
let data = Data(referencing: apnsToken);
Messaging.messaging().apnsToken = data
Messaging.messaging().token(completion: { fid, error in
completion(fid, error as NSError?)
})
}
// ...
}
注意
.NET 系結將使用的原生包裝函式 API 類型必須宣告為 public ,而且必須使用 和 方法@objc(NameOfType)來表示public,而且也可以受益於指定名稱和參數的類似批注@objc(methodName:parameter1:),這有助於影響將產生哪些目標夏皮的系結。
您可以在此方法中看到,公用 API 介面只會使用 iOS 的 .NET 已經知道的類型:NSData、 StringNSError 和回呼。
在 Firebase.MaciOS.Binding 專案中, ApiDefinitions.cs 檔案包含這個原生包裝函式 API 的系結定義:
using System;
using Foundation;
namespace Firebase
{
// @interface MauiFIRMessaging : NSObject
[BaseType (typeof(NSObject))]
interface MauiFIRMessaging
{
[Static]
[Export ("register:completion:")]
[Async]
void Register (NSData apnsToken, Action<string?, NSError?> completion);
// ...
}
假設您想要新增取消註冊的方法。 Swift 程式代碼看起來會像這樣:
@objc(unregister:)
public static func unregister(completion: @escaping (NSError?) -> Void) {
// need delegate to watch for fcmToken updates
Messaging.messaging().deleteToken(completion: { error in
completion(error as NSError?)
})
}
另一半是更新系結專案中的ApiDefinitions.cs檔案,以公開這個新方法。 有兩種方式可以解決此問題:
- 您可以手動新增必要的程式碼
- 建置系結項目之後,您可以運行 Objective Sharpie 工具來產生 ApiDefinitions.cs 檔案。 您可以嘗試尋找此檔案的相關變更,並手動複製這些變更,或嘗試複製整個檔案,並查看差異以尋找您需要的部分。
在此情況下,ApiDefinitions.cs的變更會是:
[Static]
[Export("unregister:")]
[Async]
void UnRegister(Action completion);
進行這些變更之後,您可以重建系結專案,而新的 API 將會準備好從 .NET MAUI 專案使用。
注意
Mac/iOS 的系結專案不會使用來源產生器,因此專案系統和 Intellisense 在重建系結專案之前,可能無法知道新的 API,並重載方案,讓專案參考挑選較新的元件。 不論 Intellisense 錯誤為何,您的應用程式專案仍應該編譯。
Android
在 Android Studio 專案中,您會發現模組目錄,其中包含定義系結之公用 API 介面的 Java 檔案。 例如, initialize Facebook 的 方法定義如下:
package com.microsoft.mauifacebook;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
import com.facebook.LoggingBehavior;
import com.facebook.appevents.AppEventsLogger;
public class FacebookSdk {
static AppEventsLogger _logger;
public static void initialize(Activity activity, Boolean isDebug) {
Application application = activity.getApplication();
if (isDebug) {
com.facebook.FacebookSdk.setIsDebugEnabled(true);
}
com.facebook.FacebookSdk.addLoggingBehavior(LoggingBehavior.APP_EVENTS);
AppEventsLogger.activateApp(application);
_logger = AppEventsLogger.newLogger(activity);
}
// ...
}
您可以在此方法中看到,公用 API 介面只會使用適用於 Android 的 .NET 已經知道的類型: Activity 和 Boolean。
在 Facebook.Android.Binding 一般而言,Android 系結比目前 Mac/iOS 更「自動」,您很少需要對這些轉換檔案進行變更。
<metadata>
<attr path="/api/package[@name='com.microsoft.mauifacebook']" name="managedName">Facebook</attr>
</metadata>
假設您想要新增方法來記錄事件。 Java 程式代碼看起來會像這樣:
public static void logEvent(String eventName) {
_logger.logEvent(eventName);
}
從這個簡單的變更中,系結專案不需要更新 Transforms/Metadata.xml 或其他檔案。 您只要重建系結專案,新的 API 就會準備好從 .NET MAUI 專案使用。
注意
Android 的系結專案不會使用來源產生器,因此專案系統和 Intellisense 在重建系結專案之前,可能不知道新的 API,並重載方案,讓專案參考挑選較新的元件。 不論 Intellisense 錯誤為何,您的應用程式專案仍應該編譯。