MSVC リンカーは、オブジェクト ファイル (.obj) とオブジェクト ライブラリ (.lib) をリンクして、.EXE または .DLL を生成できます。
DLL とリンクするには、MSVC でのプロセスは、C 関数名と DLL のエクスポート テーブルの間の接着剤として機能する、いわゆるインポート ライブラリ (.LIB) を使用することです (DLL では、関数は名前または序数による - 後者は文書化されていない API によく使用されていました)。
ただし、ほとんどの場合、DLL エクスポート テーブルにはすべての関数名が含まれているため、インポート ライブラリ (.LIB) にはほとんど冗長な情報が含まれています ("インポート関数 ABC -> エクスポートされた関数 ABC 」など)。
既存の .DLL から .LIB を生成することさえ可能です。
他のプラットフォームのリンカーにはこの「機能」がなく、動的ライブラリと直接リンクできます。
Linux では、リンカー (ダイナミック リンカーではない) は、リンク時に指定された共有ライブラリを検索し、実行可能ファイル内にそれらへの参照を作成します。ダイナミック リンカーがこれらの実行可能ファイルを読み込むと、必要な共有ライブラリがメモリに読み込まれ、シンボルが解決されるため、バイナリを実行できるようになります。
MySo.a
rustyx's answer は、Windows でのプロセスを私よりも徹底的に説明しています。 Windows を使うのは久しぶりです。
あなたが見ている違いは実装の詳細です.LinuxとWindowsの両方が同様に動作します.コードは実行可能ファイルに静的にリンクされているスタブ関数を呼び出し、このスタブは必要に応じてDLL/shlibをロードします(遅延の場合)それ以外の場合は、プログラムの開始時にライブラリがロードされます)、(最初の呼び出しで) GetProcAddress
を介してシンボルを解決します /dlsym
.
唯一の違いは、Linux ではこれらのスタブ関数 (PLT スタブと呼ばれる) が動的に生成されることです。 アプリを動的ライブラリにリンクすると (ライブラリにはそれらを生成するのに十分な情報が含まれます)、Windows では代わりに DLL 自体が作成されるときに別の .lib
で生成されます。 ファイル。
2 つのアプローチは非常に似ているため、Linux で Windows インポート ライブラリを模倣することは実際に可能です (Implib.so プロジェクトを参照してください)。