1. ホーム
  2. c#

[解決済み] DLLには何が入っていて、どのように動作するのですか?

2023-04-07 18:49:55

質問

C#のコードでいつもDLLを参照しているのですが、なんだか謎のままなので明らかにしたいと思います。これは、DLLに関する質問のブレインダンプのようなものです。

DLL は動的にリンクされたライブラリであり、他のプログラムが実行時にこのライブラリにアクセスして機能性を得ることができることを意味すると理解しています。しかし、次のような ASP.NET プロジェクトを考えてみましょう。 Web.dllBusiness.dll ( Web.dll はフロントエンドの機能であり、これは Business.dll を参照します)。

  1. どの時点で Web.dll に動的にリンクするのでしょうか? Business.dll ? Word (など) を使用しているときに、一見小さなタスクでも Windows の HDD がスラッシングすることに多く気付きます。Word が暴走して、他の DLL から機能を動的にリンクしているのでは?

    1a. さらに、OS や .NET フレームワークのようなランタイム フレームワークなど、何が DLL をロードしリンクするのでしょうか?

    1b. リンクのプロセスは何ですか。 互換性チェックは行われていますか? 同じメモリに読み込むのですか? リンクとは実際に何を意味するのですか?

  2. DLL 内のコードは実際に何が実行するのでしょうか。プロセッサによって実行されるのでしょうか、それともプロセッサが DLL 内のコードを理解する前に、翻訳やコンパイルの別の段階があるのでしょうか。

    2a. C# .NETで構築されたDLLの場合、これを実行しているのは.NETフレームワークなのか、それとも直接オペレーティング システムなのでしょうか?

  3. Linux からの DLL は Windows システム上で動作しますか (そのようなものが存在する場合)、それともオペレーティング システム固有のものですか?

  4. DLL は特定のフレームワークに固有のものですか? C# .NET を使用して構築された DLL を、たとえば Borland C++ で構築された DLL が使用することはできますか?

    4a. もし4への答えが「いいえ」なら、DLLのポイントは何でしょうか? なぜさまざまなフレームワークがリンクされたファイルに対して独自の形式を使用しないのでしょうか? たとえば、.NET でビルドされた .exe は、.abc のファイル タイプがコードにリンクできるものであることを知っています。

  5. に戻ると Web.dll / Business.dll 例 - 顧客というクラスタイプを取得するためには、次のように参照する必要があります。 Business.dll から Web.dll . これはつまり Business.dll には、顧客クラスが実際に何であるかについてのある種の仕様が含まれているということです。もし私が Business.dll ファイルをコンパイルした場合、C# はそれを理解して顧客クラスを作成できるでしょうか。それとも、ヘッダー情報か何かがあり、「別の Delphi DLL" からしか私を使用できないのは申し訳ない」と言うでしょうか。

    5a. 同じことがメソッドにも当てはまります。 CreateInvoice() メソッドを DLL で書き、C++ でコンパイルし、C# からアクセスして実行することはできますか?これを止める、あるいは可能にするものは何でしょうか?

  6. DLL のハイジャックについてですが、確かに、置き換えられた (悪い) DLL は、ハイジャックされているものと同じメソッド署名と型を含んでいる必要があります。元の DLL で利用可能なメソッドを見つけることができれば、これを行うのは難しくないと思います。

    6a. 私のC#プログラムの中で、別のDLLにアクセスできるかどうかを決定しているのは何ですか? もし私の乗っ取られた DLL がオリジナルとまったく同じメソッドと型を含んでいて、別の言語でコンパイルされていたら、それは動作しますか?

DLLインポートおよびDLL登録とは何ですか?

どのように解決するのですか?

まず第一に、2 つの非常に異なる種類の DLL の違いを理解する必要があります。Microsoft は、.NET (マネージ コード) とネイティブ コードの両方で同じファイル拡張子 (.exe と .dll) にすることを決定しましたが、マネージ コード DLL とネイティブ DLL は 非常に 内部は異なっています。

<ブロッククオート

1) web.dll はどの時点で business.dll に動的にリンクするのでしょうか。あなたは Windows では、Word などを使用する際に、一見小さなタスクでも HDD がスラッシングすることによく気がつきます。 Word などを使用していると、この Word が暴走して他の DLL から機能を動的にリンクしているのではないかと思います。 他の DLL から機能を動的にリンクしているのでは?

ブロック クォート

1) .NETの場合、DLLは通常、DLLから何かにアクセスしようとする最初のメソッドが実行されるときにオンデマンドでロードされます。このため、DLL を読み込むことができない場合、コード内の任意の場所で TypeNotFoundException を取得することができます。Wordのようなものが突然HDDに大量にアクセスし始めた場合、スワッピング(RAMに空きを作るためにディスクにスワップされたデータを取得すること)している可能性があります。

<ブロッククオート

1a) さらに、DLLをロードしリンクするのは何か。 それとも .Net フレームワークのようなランタイム・フレームワークですか?

1a) マネージドDLLの場合、.NETフレームワークはDLLをロードし、JITコンパイル(.NETバイトコードをネイティブコードにコンパイル)し、リンクさせるものです。ネイティブ DLL の場合、DLL をロードしリンクするのはオペレーティング システムのコンポーネントです (ネイティブ DLL はすでにネイティブ コードを含んでいるので、コンパイルは必要ありません)。

1b) リンクのプロセスはどのようなものですか。互換性があることを確認するために 互換性はありますか?同じメモリに読み込むのですか?リンクとは を意味するのでしょうか?

1b) リンクとは、呼び出し側のコードで DLL 内のシンボル (メソッドなど) への参照 (メソッド呼び出しなど) を DLL 内のものの実際のアドレスに置き換えることです。これは、DLL がメモリにロードされる前に DLL 内のものの最終的なアドレスを知ることができないため、必要なことです。

2) DLL内のコードを実際に実行するのは何ですか? それはプロセッサによって実行されるのでしょうか。 それとも、プロセッサが DLL 内のコードを理解する前に、別の翻訳またはコンパイルの段階があるのでしょうか。 プロセッサが DLL 内のコードを理解する前に、別の翻訳またはコンパイル段階があるのでしょうか?

2) Windows では、.exe ファイルと .dll ファイルはまったく同じものです。ネイティブの .exe と .dll ファイルにはネイティブ コード (プロセッサが実行するものと同じもの) が含まれているため、翻訳する必要はありません。マネージド .exe および .dll ファイルには、最初に JIT コンパイルされる (ネイティブ コードに翻訳される) .NET バイトコードが含まれます。

2a) C# .netからビルドされたDLLの場合、これを実行しているのは何ですか?それは .Net フレームワークなのか、それともオペレーティング システムなのか?

2a) コードはJITコンパイルされた後、他のコードと全く同じ方法で実行されます。

3) 例えば Linux からの DLL は Windows システム (そのようなものがある場合) で動作するのでしょうか。 それともオペレーティング システム固有のものですか?

3) マネージド DLL は、両方のプラットフォームのフレームワークが最新であり、DLL を書いた人がネイティブコールを使用して意図的に互換性を壊していない限り、そのまま動作する可能性があります。ネイティブDLLは、フォーマットが異なるため、そのままでは動作しません(同じプロセッサプラットフォーム用であれば、内部のマシンコードは同じでも)。ちなみに、Linux では、DLL は .so (共有オブジェクト) ファイルとして知られています。

4) 特定のフレームワークに特有のものなのでしょうか。C# .Net を使用してビルドされた DLL は C# .Net でビルドした DLL を Borland C++ でビルドした DLL で使用できますか (例のみ)?

4) マネージドDLLは.NETフレームワーク特有のものですが、当然ながら互換性のあるどの言語でも動きます。ネイティブ DLL は、誰もが同じ規約 (呼び出し規約 (関数の引数がマシン コード レベルでどのように渡されるか) 、シンボルの命名など) を使用する限り、互換性があります。

5) web.dll / business.dll の例に戻ります。クラス タイプを取得するために、私は web.dll から business.dll を参照する必要があります。これは これは、business.dll が顧客クラスが実際に何であるかについてのある種の仕様を含んでいることを意味します。 これは、business.dll が customer クラスが実際に何であるかのある種の仕様を含んでいることを意味します。もし、私のbusiness.dllをDelphiでコンパイルしていたとしたら、C#はそのようなことをするでしょうか? ファイルをコンパイルしたら、C#はそれを理解し、顧客クラスを作成することができるでしょうか? それとも、ヘッダー情報か何かがあるのでしょうか? というヘッダー情報か何かがあるのでしょうか?

5) マネージド DLL は、それらが含むすべてのクラス、メソッド、フィールドなどの完全な説明を含んでいます。AFAIK Delphi は .NET をサポートしていないので、ネイティブ DLL を作成することになり、.NET でそのまま使用することはできません。PInvokeで関数を呼び出すことはできるだろうが、クラス定義は見つからないだろう。私はDelphiを使っていないので、DLLで型情報をどのように保存しているかはわかりません。たとえば C++ では、型宣言を含むヘッダー (.h) ファイルに依存し、DLL とともに配布する必要があります。

6) DLL のハイジャックについてですが、確かに置換された (悪い) DLL は、正確なメソッド署名や、型宣言を含んでいなければなりません。 は、乗っ取られたものとまったく同じメソッド署名、型を含んでいなければなりません。 を含んでいなければなりません。これは、もしあなたが以下のことを見つけることができれば、難しいことではないでしょう。 元のDLLでどのようなメソッドなどが利用可能であったかを知ることができれば、これは難しいことではないと思います。

6) 確かに、DLLを簡単に切り替えられるのであれば、難しいことではありません。コード署名を使えば、これを回避することができます。誰かが署名されたDLLを置き換えるためには、それが秘密にしている署名キーを知らなければなりません。

6a) 少し繰り返しの質問になりますが、これは、私の C# プログラムは、別の DLL にアクセスできるかどうかを決定しているのでしょうか? もし私のハイジャックされたDLL がオリジナルと全く同じメソッドと型を含んでいたとしても、それは別の言語でコンパイルされています。 別の言語でコンパイルされていた場合、それは動作するのでしょうか?

6a) 任意の.NET言語で作成されたマネージドDLLである限り、動作します。

  • DLLインポートとは何ですか? とDLL登録とは何ですか?

DLLインポートとは、様々な意味がありますが、通常はDLLファイルを参照し、その中のものを使用することを意味します。

DLL 登録は Windows で行われるもので、DLL ファイルを COM コンポーネントとしてグローバルに登録し、システム上のあらゆるソフトウェアで利用できるようにするものです。