在 ILMerge SkiaSharp 进入我的 Xamarin.iOS dll 后抛出 DllNotFoundException

DllNotFoundException is thrown after ILMerge SkiaSharp into my Xamarin.iOS dll

我尝试创建一个 Xamarin.iOS class 库,它在内部使用 SkiaSharp。我想将最终的 class 库作为没有外部依赖项的单个 dll 分发。为此,我使用 ILMerge(或 ILRepack)。最终的 dll 已成功创建,但是当我尝试从我的 class 库调用某些方法时,我得到 DllNotFoundException。这是堆栈跟踪:

{System.DllNotFoundException: @rpath/libSkiaSharp.framework/libSkiaSharp at (wrapper managed-to-native) SkiaSharp.SkiaApi:sk_filestream_new (string) at SkiaSharp.SKFileStream..ctor (System.String path) [0x00000] in <9d222c42d8aa4f729033b25ddebc012a>:0 at SkiaSharp.SKBitmap.Decode (System.String filename) [0x00011] in <9d222c42d8aa4f729033b25ddebc012a>:0 at TestMerge.TestClass.TestMethod (System.String imageFile) [0x00001] in <9d222c42d8aa4f729033b25ddebc012a>:0 at Tests.Xamarin.Tests.Test001 () [0x00002] in /Users/mac1/Projects/awxamarin/Xamarin.Tests/Tests.Xamarin/Tests.cs:19 }

重现步骤:

  1. 创建一个简单的 Xamarin.iOS class 库。
  2. 添加对 SkiaSharp 的引用
  3. 使用 SkiaSharp 的方法创建一些简单的 public class。例如

    namespace TestMerge
    {
        public class TestClass
        {
            public static void TestMethod(string imageFile)
            {
                SkiaSharp.SKBitmap bmp = SkiaSharp.SKBitmap.Decode(imageFile);
            }
        }
    }
    
  4. 构建项目并使用 ILMerge(如果您更喜欢 ILRepack)合并 dll。这是用于合并 dll 的命令:

    ILMerge.exe /log:C:\Temp\ILMerge.log /internalize /ndebug /targetplatform:v4,"C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\Xamarin.iOS\v1.0" /out:C:\Temp\TestMerge.dll C:\Temp\TestMerge\TestMerge\bin\Debug\TestMerge.dll C:\Temp\TestMerge\TestMerge\bin\Debug\SkiaSharp.dll

  5. 创建 Xamarin.iOS 应用程序(我使用 UnitTest 应用程序进行测试)添加对创建的 dll 的引用,调用方法 TestMethod。结果 System.DllNotFoundException: @rpath/libSkiaSharp.framework/libSkiaSharp 发生。

我试图反编译我的 dll,libSkiaSharp.framework 在那里,它作为资源嵌入,就像在 SkiaSharp.dll 中一样。 任何帮助表示赞赏,我坚持这一点。 顺便说一句,完全相同的方法适用于 Xamarin.Android.

我终于成功了。解决方案一如既往地简单 :)。要使其工作,需要将以下属性添加到主 class 库项目的 AssemblyInfo.cs 中:

[assembly: ObjCRuntime.LinkWith("libSkiaSharp.framework", SmartLink = true)]

希望这对其他人有用