GNU/Linux >> Linux の 問題 >  >> Linux

(静的にリンクされた) DLL はメイン プログラムとは異なるヒープを使用しますか?

まず、アプリケーション/DLL に関する Windows OS のヒープ割り当てとスタックを理解しましょう。従来、オペレーティング システムとランタイム ライブラリには、ヒープの実装が付属しています。

<オール>
  • プロセスの開始時に、OS はプロセス ヒープと呼ばれる既定のヒープを作成します。 Process ヒープは、他のヒープが使用されていない場合、ブロックの割り当てに使用されます。
  • 言語ランタイムは、プロセス内に個別のヒープを作成することもできます。 (たとえば、C ランタイムは独自のヒープを作成します。)
  • これらの専用ヒープに加えて、アプリケーション プログラムまたはロードされた多くのダイナミック リンク ライブラリ (DLL) の 1 つが、プライベート ヒープと呼ばれる個別のヒープを作成して使用する場合があります
  • これらのヒープは、すべての仮想メモリ システムで、オペレーティング システムの仮想メモリ マネージャーの上にあります。
  • CRT と関連するヒープについて詳しく説明しましょう。 <オール>
  • C/C++ ランタイム (CRT) アロケータ:malloc() と free()、および new と delete 演算子を提供します。
  • CRT は、その初期化の一部として、すべての割り当てに対してこのような追加のヒープを作成します (この CRT ヒープのハンドルは、_crtheap と呼ばれるグローバル変数の CRT ライブラリに内部的に格納されます)。
  • CRT は、Windows ヒープの上にある独自のプライベート ヒープを作成します。
  • Windows ヒープは、Windows ランタイム アロケータ (NTDLL) を囲む薄い層です。
  • Windows ランタイム アロケータは、OS が使用するページを予約およびコミットする仮想メモリ アロケータとやり取りします。
  • DLL と exe は、マルチスレッドの静的 CRT ライブラリにリンクしています。作成する各 DLL および exe には、独自のヒープ (_crtheap) があります。割り当てと割り当て解除は、それぞれのヒープから行う必要があります。 DLL から動的に割り当てられ、実行可能ファイルから割り当てを解除することはできず、その逆も同様です。

    何ができる? /MD または /MDd を使用して DLL および exe でコードをコンパイルし、ランタイム ライブラリのマルチスレッド固有および DLL 固有のバージョンを使用します。したがって、DLL と exe の両方が同じ C ランタイム ライブラリにリンクされているため、1 つの _crtheap にリンクされています。割り当ては、1 つのモジュール内で常に割り当て解除と対になっています。


    DLL / exe は、C ランタイム ライブラリの実装にリンクする必要があります。

    C Windows ランタイム ライブラリの場合、次へのリンクを希望する場合は、指定するオプションがあります:

    <オール>
  • シングル スレッド C ランタイム ライブラリ (シングル スレッド ライブラリのサポートは現在中止されています)
  • マルチスレッド DLL / マルチスレッド デバッグ DLL
  • 静的ランタイム ライブラリ。
  • さらにいくつか (リンクを確認できます)
  • それぞれが異なるヒープを参照するため、あるランタイム ライブラリのヒープから取得したアドレスを別のランタイム ライブラリに渡すことはできません。

    さて、あなたが話しているDLLがどのCランタイムライブラリにリンクされているかによって異なります。たとえば、使用している DLL が静的 C ランタイム ライブラリにリンクされており、アプリケーション コード (メイン関数を含む) がマルチスレッド C ランタイム DLL にリンクされているとします。 DLL をメイン プログラムに追加してそこで解放しようとしたり、その逆を行ったりすると、未定義の動作が発生する可能性があります。したがって、基本的な根本原因は C ランタイム ライブラリです。慎重に選んでください。

    サポートされている C ランタイム ライブラリの詳細については、こちらとこちらをご覧ください

    MSDN からの引用:

    注意 ランタイム ライブラリの静的バージョンと動的バージョンを混在させないでください。 1 つのプロセスに複数のランタイム ライブラリのコピーがあると、問題が発生する可能性があります。これは、1 つのコピーの静的データが他のコピーと共有されないためです。リンカーを使用すると、1 つの .exe ファイル内で静的バージョンと動的バージョンの両方をリンクできなくなりますが、ランタイム ライブラリの 2 つ (またはそれ以上) のコピーが残る可能性があります。たとえば、ランタイム ライブラリの静的 (非 DLL) バージョンにリンクされたダイナミック リンク ライブラリは、動的 (DLL) バージョンのランタイム ライブラリにリンクされた .exe ファイルと一緒に使用すると、問題を引き起こす可能性があります。 . (また、1 つのプロセスでライブラリのデバッグ バージョンと非デバッグ バージョンを混在させないようにする必要があります。)


    Linux
    1. Linuxgrepコマンドの使用方法

    2. Linuxでhistoryコマンドを使用する方法

    3. CentOS / RHEL :デフォルト ポート 20 および 21 以外のポートを使用するように vsftpd を構成する方法

    1. basenameコマンドの使用方法は?

    2. Bashでの$#の使用は何ですか

    3. 「sudo」パスワードが「su root」パスワードと異なるのはなぜですか

    1. プログラムによってアクセスされるファイルを一覧表示しますか?

    2. 使用中のWordpressのバージョンを確認してください

    3. ターミナルから呼び出されたときに、Anaconda インストールではなくデフォルトの Python を使用する