Introduction

Windows上でOpenCVのstaticライブラリを作成し、自作のdllにリンクさせる方法。

.NETでP/Invokeするとよくあるエラーの一つが、Nativeのdllが見つからないというのがあります。
例えば下記のような。

1
2
3
4
5
Unhandled exception. System.DllNotFoundException: Unable to load shared library 'XXXXXXXX' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libXXXXXXXX: cannot open shared object file: No such file or directory
at XXXXXXXX.net_Net_new(IntPtr& net)
at XXXXXXXX.Net..ctor() in /home/t-takeuchi/Work/OpenSource/YYYYYYY/src/XXXXXXXX/src/XXXXXXXX/Net/Net.cs:line 15
at YYYYYYY.YYYYYYY..ctor(YYYYYYYParameter parameter) in /home/t-takeuchi/Work/OpenSource/YYYYYYY/src/YYYYYYY/YYYYYYY.cs:line 118
at Demo.Program.Main(String[] args) in /home/t-takeuchi/Work/OpenSource/YYYYYYY/examples/Demo/Program.cs:line 35

たいていは、そのdllがないのではなく、そのdllが依存しているライブラリが存在しないというパターンが多い。
Windowsの場合は DepenecyWalker とかで割と簡単に原因がわかる。
OSXなら、 otool -L 、Linuxの場合は、 ldd を使えばわかる。

しかし、今回、Ubuntuで発生した上記エラーに対し、lddを適用したところ

1
2
3
4
5
6
7
8
9
10
11
12
$ ldd bin/Release/netcoreapp3.1/libXXXXXXXX.so 
linux-vdso.so.1 (0x00007ffdb97dd000)
libvulkan.so.1 => /usr/share/vulkan/1.1.92.1/x86_64/lib/libvulkan.so.1 (0x00007fde29b7b000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fde2995c000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fde29754000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fde29550000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fde291c7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fde28e29000)
libmvec.so.1 => /lib/x86_64-linux-gnu/libmvec.so.1 (0x00007fde28bff000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fde289e7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fde285f6000)
/lib64/ld-linux-x86-64.so.2 (0x00007fde2ac47000)

エラーが見当たらなかった。

という問題の解決方法。

How to?

タイトル通り LD_DEBUG を使います。
ググっても、使い方がわかりづらかったのですが、要するに

1
$ LD_DEBUG=symbols,bindings dotnet run -c Release 2> error.log

のように、問題が発生するコマンドと合わせて実行するということです。