C++ プログラムがリリースされたとき、依存ライブラリには解決策がありません

ヒント: 記事を作成した後、目次を自動的に生成できます。生成方法は、右側のヘルプドキュメントを参照してください。


序文

著者は最近、C++ を使用して PCL ライブラリのコードを呼び出し、そのコードを C# で使用できる DLL にパッケージ化する方法を研究しています。使用した IDE は VS2017 です。多大な苦労の末、ついにパッケージングが成功し、このマシンのテストは合格しました。しかし、dll を他の人に配布すると、次のエラーが発生します。
System.DllNotFoundException:“无法加载 DLL“PointCloudDll.dll”: 找不到指定的模块

ここに画像の説明を挿入
しかし、明らかにすべての DLL を exe と同じディレクトリに配置しているのに、なぜこのエラーが依然として発生するのでしょうか?

1. エラー分析

このエラーには通常 3 つの理由が考えられます。
第一に、パッケージ化されたコードに問題があること、
第二に、DLL のビット数がターゲット マシンのビット数と一致していないこと、第三に、
パッケージ化された DLL が他の DLL を参照しており、これらの DLL はディストリビューションに含まれていないことです。
このマシンでテストすると問題がなかったので、1 点目は除外できます。自分でパッケージした DLL は 64 ビットで、ターゲット マシンも 64 ビットに設定されているため、2 点目は除外できます。 。その問題は 3 番目の点で発生します。
ただし、パッケージ化するときに他の DLL を参照しませんでした。はい、私たちは他の DLL を自分で使用しませんでしたが、コンピューターが自動的に関連する DLL を参照しました。これは vs の DLL 検索パスに関連しています。一般に、vs の DLL 検索シーケンスは次のとおりです:
a. アプリケーションが配置されているディレクトリ。

b. システムディレクトリ。GetSystemDirectory によって返されるディレクトリは通常、システム ディスク\Windows\System32 です。

c. 16 ビットのシステム ディレクトリ。この項目は上位互換性処理のみを目的としており、無視できます。

d. Windows ディレクトリ。GetWindowsDirectory によって返されるディレクトリは通常、システム ディスク\Windows です。

e. 現在のディレクトリ。GetCurrentDirectory によって返されたディレクトリ。

f. 環境変数 PATH 内のすべてのディレクトリ

ここでのシステム ディレクトリは、32 ビット マシンでも 64 ビット マシンでも、通常は Windows\System32 です。SysWOW64 ディレクトリはないのではないかと言う人もいるかもしれません。64ビットマシンはこのディレクトリに置くべきではないでしょうか? そうではありません。WOW64 は Windows on Wondows の略称で、32 ビット プログラムと互換性を持たせるために存在します。64 ビット オペレーティング システムでは、32 ビット コードと 64 ビット コードが別々に実行され、System32 と SysWOW64 という 2 つのライブラリ フォルダーがあり、さらに 2 つのレジストリもあります。一般に、32 ビット システムの規則によれば、64 ビット DLL を保存するフォルダーは System64 と呼ばれるはずですが、実際には、互換性を維持するために、Microsoft は依然として 64 ビット DLL を System32 フォルダーに保存しています。同時に、32 ビットと互換性を持たせるために、SysWOW64 フォルダーをセットアップします。
これを理解すれば、エラーが報告された理由がわかるはずです。これは、私がパッケージ化した DLL が多くの PCL ライブラリ コードを使用しており、これらの関連する DLL をディレクトリに配置しなかったためです。しかし、ローカルマシンで実行するとエラーは発生しません。これは、このマシンで PCL ライブラリの環境変数を設定しているため、カプセル化された DLL が呼び出されるときに、DLL は PCL DLL を使用します。これらの DLL をディレクトリに配置していませんが、vs は環境変数を渡すことができます。これらの関連 DLL を検索すると、エラーは報告されなくなります。

2、解決策

関連する DLL が不足していることが問題の原因であることがわかったので、最初に行うことは、不足している DLL を見つけることです。ここでは、DLL 分析ツールを使用して、独自のパッケージ内でどの DLL も参照されているかを分析する必要があります。 dlls. ここではステーション B アップをお勧めします Hell8999 メインによって作成された分析ツール PE アナライザー、これはダウンロード リンクです
このツールを通じて、自分でパッケージ化した dll が他の多くの dll を参照していることを分析できます
ここに画像の説明を挿入

このうち、赤い矢印は PCL 関連の DLL、緑の矢印はウィンドウ システムの DLL で、通常の Windows にはこれらの DLL が入っており、青い矢印は C++ ランタイムの DLL です。ここでは、pcl の dll をディレクトリに置くだけでよく、他の dll はほとんどのコンピュータで利用できます。これら 2 つの pcl dll には、pcl_io_ply_release と OpenNI2 の 2 つの dll も参照する pcl_io_release dll などの他の dll も含まれている可能性があるため、これだけでは十分ではありません。同じエラーが報告されます。筆者はこの2つのdllを入れていなかったため、原因を調べるのに丸一日かかりました。
したがって、サードパーティ ライブラリで DLL をカプセル化する場合は、各 DLL の依存関係を確認する必要があり、DLL が 1 つ欠落しているためにプログラムでエラーが報告される可能性があります。
ここに画像の説明を挿入

要約する

サードパーティ ライブラリを使用して DLL を配布する場合は、その DLL が依存する他の DLL も一緒に配布することを忘れないでください。また、入れ子人形のように、レイヤーごとに他の DLL が他の DLL を参照する可能性があることを忘れないでください。何層設定しても配布する際は全てのdllをまとめて配布する必要があります!

おすすめ

転載: blog.csdn.net/bookshu6/article/details/125052874