具有本机库依赖关系的.NET Core项目 [英] .NET Core project with native library depedency

查看:164
本文介绍了具有本机库依赖关系的.NET Core项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在.NET Core中编写一个依赖于使用[DllImport]的本机代码的应用程序.我有用于win-x64,win-x86和linux-x64的本机编译库构件.

I am writing an app in .NET Core that depends on native code using [DllImport]. I have the native compiled library artifacts for win-x64, win-x86, and linux-x64.

我的项目结构如下:

MyApp
|--Main.cs
|--runtimes
   |--win-x86
      |--native
         |--somelibrary.dll
   |--win-x64
      |--native
         |--somelibrary.dll
   |--linux-x64
      |--native
         |--libsomelibrary.so

当我运行该应用程序时,我得到了DLL找不到异常.

I get then DLL not found exceptions when I run the app.

我尝试在此处使用MSBuild目标解决方案,但这仅在编译时将一个dll复制到主输出文件夹.但是,我希望输出在输出文件夹中包含所有三个本机库,其结构与上述运行时文件夹相同,并将兼容的本机库的选择留给.NET Core运行时主机.

I have tried to use MSBuild targets solution here, but this only copies one dll to the main output folder at compile time. However, I want to the output to include all three native libraries in the output folder in the same structure as the runtimes folder above, and leave the selection of the compatible native library to .NET Core runtime host.

因此,如果用户在Windows x86中运行该应用程序,它将使用win-x86,依此类推.

So if the user runs the app in Windows x86, it will use the win-x86, and so on.

当我从NuGet引用诸如 SkiaSharp 之类的本地包装时,我注意到,它实际上会很好地集成到我的应用程序中,并将所有资产包含在运行时文件夹结构中,以便在运行时在多个环境中工作.我该怎么办?

I have noticed when I reference native wrappers like SkiaSharp from NuGet, it will actually integrate nicely into my app, and will include all assets in a runtimes folder structure to work on multiple environments at runtime. How can I do this?

我最终为本地库绑定创建了一个nuget包,并在我的其他项目中引用了nuget.

I ended up creating a nuget package for the native library binding, and reference the nuget in my other projects.

推荐答案

这应该将您的文件夹结构复制到输出文件夹,只需将其直接放在MyApp.csproj中的第一个</PropertyGroup>下:

This should copy your folder structure to the output folder, just put it right away under the first </PropertyGroup> in your MyApp.csproj:

  <ItemGroup>
    <None Update="runtimes\**" CopyToOutputDirectory="PreserveNewest"/>
  </ItemGroup>

以防万一,有一种方法可以更好地控制如何使用程序集的DllImportResolver委托使用DllImport加载本机库.

Just in case, there is a method to have more control on how you are loading the native libraries using DllImport by DllImportResolver delegate for your assembly.

public delegate IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath);

还有一个NativeLibrary类,该类允许设置和加载.net core的本机库.一些示例代码:

There is also NativeLibrary class which allows to set and load native libraries for .net core. Some sample code:

static class Sample
{
    const string NativeLib = "NativeLib";

    static Sample()
    {
        NativeLibrary.SetDllImportResolver(typeof(Sample).Assembly, ImportResolver);
    }

    private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
    {
        IntPtr libHandle = IntPtr.Zero;
        //you can add here different loading logic
        if (libraryName == NativeLib && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitOperatingSystem)
        {
            NativeLibrary.TryLoad("./runtimes/win-x64/native/somelib.dll", out libHandle);
        } else 
        if (libraryName == NativeLib)
        {
            NativeLibrary.TryLoad("libsomelibrary.so", assembly, DllImportSearchPath.ApplicationDirectory, out libHandle);
        }
        return libHandle;
    }

    [DllImport(NativeLib)]
    public static extern int DoSomework();
}

这篇关于具有本机库依赖关系的.NET Core项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆