1

Unable to load dynamic library on Linux

  • I built a project on Mac OS and the output was a libmylibrary.so and libmylibrary.dylib files.
  • I copied the .dylib into a Visual Studio Console project and was able to load and invoke the functions of the library using the DllImport function. The project works as expected
  • I copied the project (including the .so and .dylib files) into a Ubuntu-based Docker container
  • When I run the project using dotnet run, I get the below error
System.DllNotFoundException: Unable to load shared library 'mylibrary' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(libmylibrary, 1): image not found

Edit 1
Below is the Dockerfile used to create the container

FROM streetcred/dotnet-indy AS base
WORKDIR /app

# Expose the default port
EXPOSE 5000

COPY SomeProject/ ./

RUN dotnet restore "SomeProject.csproj"
RUN dotnet build "SomeProject.csproj" -c Release -o build
RUN dotnet publish "SomeProject.csproj" -c Release -o build
RUN COPY libmylibrary.dylib build/libmylibrary.dylib
RUN COPY libmylibrary.so build/libmylibrary.so
CMD dotnet build/SomeProject.dll --urls http://0.0.0.0:5000

Edit 2
I tried the following, but I get the same error

  • Compile the mylibrary project in a Linux Docker Container (Ubuntu)
  • Copy the generated mylibrary.so file in the SomeProject

Edit 3
Based on @paladin324 comments, I tried the following, but I get the same error

LD_LIBRARY_PATH=/app/SomeProject/build
cd /app/SomeProject/build
dotnet SomeProject.dll --urls http://0.0.0.0:5000
Sahil Khanna
  • 4,262
  • 8
  • 47
  • 72
  • What does your Dockerfile look like? – Matt Thalman Sep 27 '21 at 16:42
  • @MattThalman, added the Dockerfile in the description – Sahil Khanna Sep 28 '21 at 04:24
  • MacOS isn't Linux (it's derived from FreeBSD, a Unix variant) . The services and APIs are different. `.dylib` is the extension for MacOS dynamic libraries and won't work in any Linux distribution. You'll have to recompile `mylibrary` for Linux – Panagiotis Kanavos Oct 04 '21 at 07:57
  • @PanagiotisKanavos, tried your suggestion. Getting the same error. Please refer to the `Edit 2` section in the description – Sahil Khanna Oct 04 '21 at 12:23
  • Is `mylib.so` a native (C++) library? .NET libraries are always named `.dll`, regardless of the OS. – PMF Oct 06 '21 at 15:19
  • @PMF, this is the library that I'm trying to build. It generates the libs of `.dylib` and `.so` https://github.com/hyperledger/indy-sdk/tree/master/experimental/plugins/postgres_storage – Sahil Khanna Oct 06 '21 at 16:23
  • I guess then you didn't really recompile for linux. A linux build does not give a dylib file (that's macOS-specific). Linux libraries are .so only. `file myLibrary.so` should say something like ` ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked,` – PMF Oct 06 '21 at 16:39
  • @PMF, I built the library in a Linux (Ubuntu) Container. It generated `.so`, `.a`, and a few other files. However, I get the same error with the `.so` file – Sahil Khanna Oct 07 '21 at 04:28
  • How does your `DllImport` directive look like? – PMF Oct 07 '21 at 07:33
  • @PMF, `[DllImport("myLibrary", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]` – Sahil Khanna Oct 07 '21 at 10:09
  • Could you try prepending `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/build` to `dotnet build/SomeProject.dll` to make absolutely sure that `dlopen` will search the right directory? I have a feeling that `build/` might not get searched because the CWD of the process is `/app`, not `/app/build`, so this would be a good way to ensure that. – paladin324 Oct 11 '21 at 21:25
  • @paladin324, I tried your suggestion but it didn't work. Please read the section `Edit 3` of the description. – Sahil Khanna Oct 12 '21 at 07:00
  • @SahilKhanna To pass the variable in the command environment, you need to prefix the command line with the variable assignment. Could you try `LD_LIBRARY_PATH=/app/SomeProject/build dotnet SomeProject.dll --urls http://0.0.0.0:5000` (as a single command)? – paladin324 Oct 12 '21 at 11:44
  • @paladin324, tried your suggestion. Getting the error `System.DllNotFoundException: Unable to load shared library 'mylibrary' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libmylibrary: cannot open shared object file: No such file or directory` – Sahil Khanna Oct 12 '21 at 13:23

1 Answers1

0

.NET uses the platform's naming conventions. DllImport("myLibrary") is going to look for a file named libmylibrary.so (the original filename of the binary). Try changing:

RUN COPY mylibrary.so build/mylibrary.so

to

RUN COPY mylibrary.so build/umylibrary.so
paladin324
  • 332
  • 1
  • 10
  • I have corrected the `RUN COPY` command in the `Edit 1` section of the description. I have the files `mylibrary.so`, `umylibrary.so` and `libmylibrary.so` in the build folder. However, I'm getting the same error – Sahil Khanna Oct 11 '21 at 13:13