Native P/Invoke with Mono on Linux: DllNotFound
Asked Answered
E

1

6

I'm trying to load some native linux libraries using mono. I've run mono with the debug flag:

Mono: DllImport attempting to load: 'libavformat.57'.
Mono: DllImport error loading library '/home/filoe/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug/libavformat.57': '/home/filoe/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug/libavformat.57: cannot open shared object file: No such file or directory'.
Mono: DllImport error loading library '/home/filoe/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug/libavformat.57.so': 'libavcodec.so.57: cannot open shared object file: No such file or directory'.
Mono: DllImport error loading library '/usr/lib/libavformat.57': '/usr/lib/libavformat.57: cannot open shared object file: No such file or directory'.
Mono: DllImport error loading library '/usr/lib/libavformat.57.so': '/usr/lib/libavformat.57.so: cannot open shared object file: No such file or directory'.
Mono: DllImport error loading library 'libavformat.57': 'libavformat.57: cannot open shared object file: No such file or directory'.
Mono: DllImport error loading library 'libavformat.57.so': 'libavformat.57.so: cannot open shared object file: No such file or directory'.
Mono: DllImport error loading library 'libavformat.57': 'libavformat.57: cannot open shared object file: No such file or directory'.
Mono: DllImport unable to load library 'libavformat.57: cannot open shared object file: No such file or directory'.
Mono: DllImport attempting to load: 'libavformat.57'.

There are lots of lookup positions but at least one of them SHOULD match. This is how my directory looks like:

filoe@ubuntu:~/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug$ dir
CSCore.Ffmpeg.dll     CSCore.Ffmpeg.dll.mdb  CSCore.Linux.dll.config  FFmpeg     libavformat.57  libswresample.2  LinuxSample.exe.mdb
CSCore.Ffmpeg.dll.config  CSCore.Linux.dll   CSCore.Linux.dll.mdb     libavcodec.57  libavutil.55    LinuxSample.exe  log.txt
filoe@ubuntu:~/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug$ 

As you can see, the libavformat.57 is there. So is mono telling me that it could not be found?

The following code demonstrates what is done:

Declaration of some DllImport methods:

[DllImport("avformat-57", EntryPoint = "av_register_all", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
internal static extern void av_register_all();
[DllImport("avcodec-57", EntryPoint = "avcodec_register_all", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
internal static extern void avcodec_register_all();

The project contains also a file with the name "{name of the output assembly}.config":

<configuration>
  <dllmap os="linux" dll="avcodec-57" target="libavcodec.57"/>
  <dllmap os="linux" dll="avformat-57" target="libavformat.57"/>
</configuration>

As you can see above, the mapping works fine. Mono takes "avformat-57" and translates it to "libavformat.57". Now mono searches for a library with the name "libavformat.57" or some related names like "libavformat.57.so". Mono searches within the directory of the executing assembly.

But, it does not manage to find the file it is looking for(according to the log posted above). So why?

Thanks!

Regards

Europa answered 11/12, 2016 at 18:32 Comment(6)
shared libraries have a .so extension, it is not picking up the library correctly, try renaming it and recreate the reference to the shared library?Hamartia
No, it does not mather which extensions or combinations of file names I'm using. The error message is that a file which definitely exists, can't be found by mono.Europa
show us a minimal reproducible example to demonstrate this.Hamartia
added some more details ...Europa
this line is jumping out at me... Mono: DllImport error loading library '/home/filoe/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug/libavformat.57.so': 'libavcodec.so.57: cannot open shared object file: No such file or directory'. do this, from the ~/Desktop/cscore/cscore/Samples/LinuxSample/bin/Debug directory, ln -s ./libavcodec.57 ./libavcodec.57.so we're creating a symbolic link. If that fails, do this, file ./libavcodec.57 to check, It may not be in native linux compiled binary, rather, its a win32 dll?Hamartia
This could be related with the fail due LD_LIBRARY_PATH env var, or difference between mono 64 and the library is 32 bit, or even due some missing dependencie of your library. Try to create a small C application and use dlopen to see if you can load your so successfully.Requisite
E
2

The key was to use command

ldd libavformat.57

With the following output:

linux-vdso.so.1 =>  (0x00007ffdf9bd6000)
libavcodec.so.57 => not found
libavutil.so.55 => not found
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4a74652000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f4a74439000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4a7421b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a73e56000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4a74d73000)

So I've renamed it to the suggested names and tried it again with no success. The next try with

LD_LIBRARY_PATH=./ ldd libavformat.so.57

Was successful. I've adjusted the config file and now I'm able to start the application with

LD_LIBRARY_PATH=./ mono MyApp.exe
Europa answered 18/12, 2016 at 10:56 Comment(2)
Just curious, why not install libavformat using the Ubuntu package manager?Muzzleloader
Curiously this was exactly what I've said in my comment ;)Requisite

© 2022 - 2024 — McMap. All rights reserved.