Is There a Linux Equivalent of Dllimport in .Net Core

Is there a Linux equivalent module and function for LoadLibrary() from kernel32.dll that i can call from .Net Core?

A couple of thoughts.

First, yes, DllImport (P/Invoke) works on Linux (and macOS) too.

This seems a bit strange:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate short AdcOpen([MarshalAs(UnmanagedType.LPStr)] string adcName, [MarshalAs(UnmanagedType.LPStr)] string protocol, [MarshalAs(UnmanagedType.LPStr)] string port, ref short handle, byte performSwReset);
private AdcOpen adcOpen;

With the mapping code (LoadLibrary, GetProcAddress, FreeLibrary), this seems like you are manually doing the work that .NET itself does if you do something like this - where you let .NET do the function finding and binding:

    [DllImport("ourdevice.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern short AdcOpen([MarshalAs(UnmanagedType.LPStr)] string adcName, [MarshalAs(UnmanagedType.LPStr)] string protocol, [MarshalAs(UnmanagedType.LPStr)] string port, ref short handle, byte performSwReset);

Any reason for doing it so differently?

Because if you were to do it that way, I expect the Linux version will look like this and work pretty much the same way as it does on Windows:

    [DllImport("libourdevice.so", CallingConvention = CallingConvention.Cdecl)]
private static extern short AdcOpen([MarshalAs(UnmanagedType.LPStr)] string adcName, [MarshalAs(UnmanagedType.LPStr)] string protocol, [MarshalAs(UnmanagedType.LPStr)] string port, ref short handle, byte performSwReset);

Assuming you are using the same calling convention and argument marshalling.
The only difference is the name change from "ourdevice.dll" to "libdevice.so". You will also need to place libdevice.so somewhere where it can be found; next to the application executable should work.

If you still want to do it manually via the LoadLibrary/GetProcAddress/FreeLibrary approach, you can use the roughly-equivalent methods on Linux:

  • dlopen (similar to LoadLibrary)
  • dlsym (similar to GetProcAddress)
  • dlclose (similar to FreeLibrary)

See https://stackoverflow.com/a/13492645/3561275 for examples and sample code on how to use these methods.

DllImport for Dotnet core returning DLLNotFoundException for present DLL

I have found the solution.. the library was being compiled as a .la (statically linked library) rather than a .so (shared object) library. The DllImport doesnt work with statically linked libraries so.. a recompilation of the library into a shared object library has meant it will now find the dll (I also exported LD_LIBRARY_PATH as pwd to make sure it was in the search path..).

Once this was in, the rest of the code fell into place. The matching dll import declaration for the version above was correct (from *EDIT 2 *) - using ref uint. So now I have to extend the methods supported in my interop class to fully support the library.

Thanks for your help @Sohaib Jundi

Calling p/invoke on cross platform (ubuntu/windows) with library that contains dots

Following @PavelAnikhouski 's suggestion, I tried targeting netcoreapp3.0 instead of 2.1 as I was doing previously and incorporated the example found here .

It works very smoothly, with one exception (pun not intended):

When running my unit tests, I kept getting a InvalidOperationException from the second unit test and onwards for the NativeLibrary.SetDllImportResolver method. As microsoft mentions in their documentation for the class:

Only one resolver can be registered per assembly. Trying to register a second resolver fails with an InvalidOperationException.

But I do not understand why would that be the case for my unit tests. The workaround I did was to wrap a try/catch inside public static void Register(Assembly assembly) (Map.cs). Specifically:

try
{
NativeLibrary.SetDllImportResolver(assembly, MapAndLoad);
}
catch (Exception e)
{
Console.WriteLine(e);
}

Did the trick for me.

P-Invoke in .net core with Linux

PInvoke is certainly supported (that is how all of the code that interfaces with the OS works), but not in the specific case you listed. You cannot PInvoke to a win32 binary on Linux, unless you have somehow built a function-compatible version of it for Linux yourself. More realistically, you need to find a Linux function from some other system binary which exposes similar functionality, and then use that instead.

DllImport(msvcrt.dll) not working when it runs on linux

@Damien_The_Unbeliever. Thanks for your help.
I used below code

 if (((ReadOnlySpan<byte>)slice).SequenceCompareTo((ReadOnlySpan<byte>)masterSlice) == 0)
isEqual = true;


Related Topics



Leave a reply



Submit