Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

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

I'm working on porting a .Net Core 3.1 application from windows to Linux. I have a ourdevice.dll on windows, and the equivalent ourdevice.so built for Linux. This dll is a native dll that we are using on windows with a pinvoke wrapper.

We load the functions from the native dll using DllImports from kernel32.dll

    [DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)]
    public static extern IntPtr LoadLibrary(string dllToLoad);

    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

    [DllImport("kernel32.dll")]
    public static extern bool FreeLibrary(IntPtr hModule);

We create delegates for each of the funtions to import:

    [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;

Then we map all the native functions something like this:

        IntPtr pAddressOfFunction;

        pDll = LoadLibrary(LibraryName);

        // check if library is loaded
        if (pDll != IntPtr.Zero)
        {
            // get proc address of the native functions
            pAddressOfFunction = GetProcAddress(pDll, "AdcOpen");
            if (pAddressOfFunction != IntPtr.Zero)
                adcOpen = (AdcOpen)Marshal.GetDelegateForFunctionPointer(pAddressOfFunction, typeof(AdcOpen));
            else
                message += "Function AdcOpen not found\n";
          
            //snip loading all the exported functions

        }

In the Linux application, obviously, we can't use kernel32.dll. We are writing C# in .Net core on Linux, and we have the native module ourdevice.so. How can I import the functions from the native Linux module into our C# wrapper? Is it even possible?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

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.

over 4 years ago · Santiago Trujillo Relatório

0

LoadLibrary:

[DllImport("libdl", ExactSpelling = true)]
public static extern IntPtr dlopen(string filename, int flags);

GetProcAddress:

[DllImport("libdl", ExactSpelling = true)]
public static extern IntPtr dlsym(IntPtr handle, string symbol);

FreeLibrary:

[DllImport("libdl", ExactSpelling = true)]
public static extern int dlclose(IntPtr handle);

Sample usage:

const int RTLD_NOW = 0x002;
IntPtr pDll = dlopen("ourdevice.so.0", RTLD_NOW);
IntPtr pAddressOfFunction = dlsym(pDll, "AdcOpen");
...
dlclose(pDll);
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda