Node.JS
Node.JS

Reputation: 1578

.NET Core linking unmanaged binaries in linux

I am trying to use libshout with C# on ubuntu and I am failing to link binaries.

I added this to my .csproj

<ItemGroup>
    <None Include="libshout.so">
        <Pack>true</Pack>
        <PackagePath>/usr/lib/x86_64-linux-gnu/</PackagePath>
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
</ItemGroup>

In my C# code I have:

[DllImport("libshout.so", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern void shout_init();

I can see the binary exist

/usr/lib/x86_64-linux-gnu/libshout.so.3.2.0

I get this error:

Microsoft.Common.CurrentVersion.targets(4601, 5): [MSB3030] Could not copy the file "/home/pc/RiderProjects/icecast-radio-broadcast/Api/libshout.so" because it was not found.

I appreciate any help or hint. Thanks

Upvotes: 2

Views: 1085

Answers (2)

omajid
omajid

Reputation: 15213

You can use the NativeLibrary class to change where libshout.so is looked up.

static class LibshoutInterop
{
    const string Libshout = "libshout";

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

    private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
    {
        IntPtr libHandle = IntPtr.Zero;
        if (libraryName == Libshout)
        {
            // Where where this is looked up
            NativeLibrary.TryLoad("/usr/lib/x86_64-linux-gnu/libshout.so", assembly, DllImportSearchPath.System32, out libHandle);
        }
        return libHandle;
    }

    [DllImport(LibShout, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall))]
    public static extern int shout_init();
}

Tom Deseyn did a more detailed writeup here: https://developers.redhat.com/blog/2019/09/06/interacting-with-native-libraries-in-net-core-3-0/

Upvotes: 3

Christopher Clark
Christopher Clark

Reputation: 23

it appears to be that when you specify. DllImport("libshout.so" it looks at the relative path to your execution environment. You could try copying or linking the lib to the directory where your app is running or you could provide an absolute path to the DllImport, it will need to have the permissions to read the file as well.

Upvotes: 1

Related Questions