如何调试从 iPhone 模拟器或设备抛出的 DllNotFoundException 以获得本机依赖项?

问题描述 投票:0回答:1

我正在开发一个适用于 Android、iOS 和桌面操作系统的 .NET 库。它在任何地方都运行良好——除了 iOS。事实上,在 iOS 上,我让它可以用于本地部署,但 Apple Store 拒绝了基于它的应用程序,因为本机依赖项必须位于 Apple“框架”中。

因此,我做了很多研究并了解了 xcframeworks 框架,并重构了我的 nupkg 以在 xcframework 结构中传递本机依赖项。这样,iOS csproj 就会构建并部署 .NET 程序集及其与应用程序的本机依赖项,但应用程序现在在尝试加载该本机依赖项时会抛出

DllNotFoundException

Visual Studio 调试输出窗口仅显示此问题:

**System.DllNotFoundException:** 'nerdbank_qrcodes'

我如何调试这个?

或者,我做错了什么?这是我的 nupkg 的布局:

D:\PACKAGES\NUGET\NERDBANK.QRCODES\0.2.55-BETA-G209A879921
|   .nupkg.metadata
|   nerdbank.qrcodes.0.2.55-beta-g209a879921.nupkg
|   nerdbank.qrcodes.0.2.55-beta-g209a879921.nupkg.sha512
|   nerdbank.qrcodes.nuspec
|   README.md
|   THIRD_PARTY_DEPENDENCIES.txt
|   THIRD_PARTY_LICENSES.yml
|   
+---lib
|   +---net8.0
|   |       Nerdbank.QRCodes.dll
|   |       Nerdbank.QRCodes.xml
|   |       
|   +---net8.0-ios17.5
|   |   |   Nerdbank.QRCodes.dll
|   |   |   Nerdbank.QRCodes.xml
|   |   |   
|   |   \---Nerdbank.QRCodes.resources
|   |       |   manifest
|   |       |   
|   |       \---nerdbank_qrcodes.xcframework
|   |           |   Info.plist
|   |           |   
|   |           +---ios-arm64
|   |           |   \---nerdbank_qrcodes.framework
|   |           |           Info.plist
|   |           |           nerdbank_qrcodes
|   |           |           
|   |           \---ios-arm64_x86_64-simulator
|   |               \---nerdbank_qrcodes.framework
|   |                       Info.plist
|   |                       nerdbank_qrcodes
|   |                       
|   \---net8.0-windows7.0
|           Nerdbank.QRCodes.dll
|           Nerdbank.QRCodes.xml
|           
\---runtimes
    +---android-arm64
    |   \---native
    |           libnerdbank_qrcodes.so
    |           
    +---android-x64
    |   \---native
    |           libnerdbank_qrcodes.so
    |           
    +---linux-arm64
    |   \---native
    |           libnerdbank_qrcodes.so
    |           
    +---linux-x64
    |   \---native
    |           libnerdbank_qrcodes.so
    |           
    +---osx-arm64
    |   \---native
    |           libnerdbank_qrcodes.dylib
    |           
    +---osx-x64
    |   \---native
    |           libnerdbank_qrcodes.dylib
    |           
    +---win-arm64
    |   \---native
    |           nerdbank_qrcodes.dll
    |           
    \---win-x64
        \---native
                nerdbank_qrcodes.dll

本机框架 dll 是使用

lipo
install_name_tool
chmod
专门准备的,如下:

# copy Info.plist and the binary into the appropriate .framework directory structure
# so that when NativeBindings.targets references it with ResolvedFileToPublish, it will be treated appropriately.
$RustTargetBaseDir = "$repoRoot/src/nerdbank-qrcodes/target"
$RustDylibFileName = "libnerdbank_qrcodes.dylib"
$DeviceRustOutput = "$RustTargetBaseDir/aarch64-apple-ios/$Configuration/$RustDylibFileName"
$SimulatorX64RustOutput = "$RustTargetBaseDir/x86_64-apple-ios/$Configuration/$RustDylibFileName"
$SimulatorArm64RustOutput = "$RustTargetBaseDir/aarch64-apple-ios-sim/$Configuration/$RustDylibFileName"

$DeviceFrameworkDir = "$repoRoot/bin/$Configuration/device/nerdbank_qrcodes.framework"
$SimulatorFrameworkDir = "$repoRoot/bin/$Configuration/simulator/nerdbank_qrcodes.framework"
New-Item -Path $DeviceFrameworkDir,$SimulatorFrameworkDir -ItemType Directory -Force | Out-Null

Write-Host "Preparing Apple iOS and iOS-simulator frameworks"

Copy-Item $IntermediatePlistPath "$DeviceFrameworkDir/Info.plist"
Copy-Item $IntermediatePlistPath "$SimulatorFrameworkDir/Info.plist"
Write-Host "Created Info.plist with version $version"

if ($IsMacOS) {
    # Rename the binary that contains the arm64 architecture for device.
    lipo -create -output $DeviceFrameworkDir/nerdbank_qrcodes $DeviceRustOutput
    install_name_tool -id "@rpath/nerdbank_qrcodes.framework/nerdbank_qrcodes" "$DeviceFrameworkDir/nerdbank_qrcodes"
    chmod +x "$DeviceFrameworkDir/nerdbank_qrcodes"

    # Create a universal binary that contains both arm64 and x64 architectures for simulator.
    lipo -create -output $SimulatorFrameworkDir/nerdbank_qrcodes $SimulatorX64RustOutput $SimulatorArm64RustOutput
    install_name_tool -id "@rpath/nerdbank_qrcodes.framework/nerdbank_qrcodes" "$SimulatorFrameworkDir/nerdbank_qrcodes"
    chmod +x "$SimulatorFrameworkDir/nerdbank_qrcodes"
}

完整上下文

ios xamarin xamarin.ios msbuild
1个回答
0
投票

事实证明,我最后缺少的就是更改我在

DllImportAttribute
中使用的库名称:

#if IOS
    // https://github.com/xamarin/xamarin-macios/issues/21238
    private const string LibraryName = "@rpath/nerdbank_qrcodes.framework/nerdbank_qrcodes";
#else
    private const string LibraryName = "nerdbank_qrcodes";
#endif
© www.soinside.com 2019 - 2024. All rights reserved.