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 toLoadLibrary
)dlsym
(similar toGetProcAddress
)dlclose
(similar toFreeLibrary
)
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
Why Can't Reference to Child Class Object Refer to the Parent Class Object
How to Get The Checkboxlist Selected Values, What I Have Doesn't Seem to Work C#.Net/Visualwebpart
Convert JavaScript Regex to C#
Scraping Data Dynamically Generated by JavaScript in HTML Document Using C#
Changing a C# Delegate's Calling Convention to Cdecl
Linux to Windows Bad Encoding Response
Asp .Net Button - Onclientclick="Return Function()" Vs Onclientclick="Function()"
Asp.Net/HTML: HTML Button's Onclick Property Inside ASP.NET (.Cs)
How to Add a Local Script File to The HTML of a Webbrowser Control
Xamarin Java.Exe Exited with Code 1 (Proguard Issue)
How to Determine a Timezone by The Utc Offset
How to Inject JavaScript in The Wp7 Webbrowser Control
Dynamic Form Generation in Asp.Net
C# Winforms Application to Linux
Parsing a Auto-Generated .Net Date Object with JavaScript/Jquery