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

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

问题描述

我正在使用 [DllImport] 在 .NET Core 中编写一个依赖于本机代码的应用程序.我有适用于 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.

我的项目结构是这样的:

My project structure is like:

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

当我运行应用程序时,我得到了 DLL not found 异常.

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 核心设置和加载本机库.一些示例代码:

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.Is64BitProcess)
        {
            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天全站免登陆