DllNotFoundException: Unable to load DLL

unityでタイトルのようなエラーが出たので調べた内容をメモ。

該当のファイルを確認すると確かに存在していたがファイルサイズが明らかに小さすぎる。なので中身を確認するとgit lfsのメタファイルになっていた。こういうやつ。

version https://git-lfs.github.com/spec/v1
oid sha256:44a8486abdf0330a3fe6b586e407506e738fe075fe0b5dfc43961e358fda7206
size 2684586

Unity - Manual: Log files

ドキュメントに従ってpackage managerのログを見てみる

# ~/Library/Logs/Unity/upm.log
[ERROR] Error when executing Git command:
git lfs pull --include <package path>
- message: `/usr/bin/git lfs pull --include <package path>` failed with code 1

- stderr: git: 'lfs' is not a git command. See 'git --help'.
...

lfsが見つからないという状態だった。

気になるのは /usr/bin/git を呼んでいる点。おそらくpackage managerには自分のシェルで設定しているPATHは通ってないので、デフォルトのものを参照していると考えられる。

ちなみに自分のシェルで確認するとちゃんとlfsもインストールされてるように見える。

$ /usr/bin/git lfs version   
git-lfs/3.2.0 (GitHub; darwin arm64; go 1.18.2)

しばらく考えつついろいろ見てると、brewでインストールしたgitも同じversionのlfsを使っていることに気づく。

$ /opt/homebrew/bin/git lfs version
git-lfs/3.2.0 (GitHub; darwin arm64; go 1.18.2)

/opt/homebrew/binにPATHを通さずに実行してみると

$ /usr/bin/git lfs version   
git: 'lfs' is not a git command. See 'git --help'.

ということで、gitコマンド内でPATHを参照してlfsにアクセスしているということだった。なのでPATHの設定がされていないpackage managerだと当然見つからない。

ここでようやく気づいたが、git lfsはgit-lfsという実体を呼んでいるだけだった。でgit-lfsbrewでインスールしてあるので/opt/homebrew/binにある。

よって以下のどちらかで解決できそう

  • package managerにbrewのpathを通す
  • デフォルトで通ってるpathにgit-lfsを置く

一つ目の方法を少し調べてみたがこのようなFAQが見つかった

環境変数を設定した状態で Unity を起動するにはどうすればいいですか? – Unity

wrapperスクリプトを書いて呼び出せとのこと。それは面倒なので2つ目の方法でとりあえず解決することに。

.zprofileや.zshrcなどの設定ファイルを除いてから起動したシェルでPATHを確認するとこうなっていた。

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Mono.framework/Versions/Current/Commands

なので/usr/local/binシンボリックリンクを貼っておく。

ln -s /usr/local/bin/git-lfs /opt/homebrew/bin/git-lfs

これでupm.logのエラーは出なくなり、dllは正しく解決されて実体がダウンロードできた。

ちなみにapple siliconの場合に/opt/homebrew/binが使われるのはrosetta2との共存のためとのこと。

FAQ — Homebrew Documentation

intel macの場合、デフォルトでbrew/usr/local/binシンボリックリンクを貼ってくれていたために労せず動いてたということだった。 apple silicon対応のために/usr/local/binはrosseta2用になったのでシンボリックリンクは貼られず、今回のようなことが起きるということがわかった。

他のツール利用時でもこれと同じことに引っかかるのは目に見えてるので今度あればこのあたりを疑ってみることにする。

clangで#inclue <bits/stdc++.h>

c++で競プロ関連の調べ物をしていると、includeの手間を省くためにbits/stdc++.hをincludeする例が多い。

clangでもstdc++.hを使うための設定方法をメモしておく。

clang++のheaderファイルのsearch pathを確認

$ clang++ -x c++ -v -E /dev/null
...
#include <...> search starts here:
 /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/c++/v1
 /Library/Developer/CommandLineTools/usr/lib/clang/13.0.0/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include
 /Library/Developer/CommandLineTools/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks (framework directory)
End of search list.
...

上記のディレクトリ内が再帰的にsearchされるので、どれかにbits/stdc++.hを作っておけばincludeできるようになる。

$ cd  /Library/Developer/CommandLineTools/usr/include
$ sudo mkdir bits
$ curl -o bits/stdc++.h  https://gist.githubusercontent.com/reza-ryte-club/97c39f35dab0c45a5d924dd9e50c445f/raw/47ecad34033f986b0972cdbf4636e22f838a1313/stdc++.h

ちなみにstdc++.hが何なのかという点についてはこちらのqiitaがわかりやすい

で、結局 #include <bits/stdc++.h> って何? - Qiita

参考

AtCoder用C++開発環境 (Mac編) | Ray's Note

gcc のインクルードパスを確認する - ユユユユユ

RSAではなくED25519

ssh keyを生成しようと参考にしたgithubのhelpページで以下のように鍵を生成するよう書かれていた。

ssh-keygen -t ed25519 -C "your_email@example.com"

https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

大抵ssh keyを作る場合は前回から年単位で時間が経っているため、rsaのbits長の目安を知るためにgithubのヘルプを見るようにしていた。そうしたところ今回はそもそもrsaじゃないタイプを使うよう書かれていたのでメモ。

まずED25519とは

エドワーズ曲線デジタル署名アルゴリズム - Wikipedia

ではEdDSAやRSAの違いは何か、についてはこちらが簡潔で概要がわかりやすかった

SSHの公開鍵暗号には「RSA」「DSA」「ECDSA」「EdDSA」のどれを使えばよいのか? - GIGAZINE

また、もう少し具体的な部分についての話だとこちらのqiitaの解説があった

電子署名EdDSA(ed25519)の数的構造 - Qiita

RSA

  • 大きな素数因数分解が困難であることを利用
  • 古くからあり最も広く使われており種々の言語でライブラリが用意されている
  • セキュリティ確保のために鍵長を長くする必要がありパフォーマンスがよいわけではない
  • 特定の整数を効率よく素因数分解するためのアルゴリズムが存在するためそのような数にあたってしまうとセキュリティ上よくない

DSA

  • 離散対数問題の困難性を利用
  • 比較的古くライブラリは充実している
  • 鍵生成時に乱数を生成しそれを秘匿する必要があることがセキュリティ上ネック
    • 質のよい乱数を生成することは難しく、実装ミスで法則を持った乱数になってしまうとその乱数の解析で暗号を突破される恐れがある
  • そのためOpenSSH7.0からはデフォルトで無効化されている

EdDSA

  • 楕円曲線上の点に対する離散対数問題を利用
  • 比較的新しい暗号であるため実装がない言語などもある
  • DSAにおける秘匿すべき乱数を、乱数として生成するのではなくハッシュとして生成することでDSAの問題を克服しセキュリティ向上
  • エドワーズ曲線を用いることで鍵長が小さく済み高速

ということでまとめると

  • RSAに比べて新しい分普及度は低いものの
  • 鍵長が短くセキュリティ的にも向上している比較的新しい暗号であるEdDSA
  • の一種であるEd25519がgithubでも推奨されるようになった

ということだとわかった。

ちなみに話題的に関連しているので紹介だが、そもそもの入門として公開鍵暗号についてはこちらの本がとてもわかりやすい。

タイトルの通り9つの社会に影響を与えたアルゴリズムについて紹介している本で、数学的な部分は比喩で説明してありアルゴリズムの全体像把握から計算手法まで大変わかりやすく解説されていた。会社で新卒におすすめの本(技術書)はと聞かれたら思い浮かぶものの一つ。