いくつかの理由が考えられます。
- .lib ファイルを使用すると、正しい SDK がインストールされていれば、システムにあるものとは異なるバージョンの DLL 用にビルドできます。
- コンパイラとリンカはクロスプラットフォーム コンパイルをサポートする必要があります - 32 ビット プラットフォームで 64 ビット ターゲット用にビルドし、その逆も同様で、正しいアーキテクチャ DLL が存在しない可能性があります。
- .lib ファイルを使用すると、実装の特定の部分を「隠す」ことができます。.lib には表示されないが、GetProcAddress を介して検出できるプライベート エクスポートを持つことができます。また、序数のエクスポートを行うこともできます。この場合、エクスポートされたフレンドリ名はありませんが、.lib にはフレンドリ名があります。
- ネイティブ DLL には厳密な名前がないため、間違ったバージョンの DLL を取得する可能性があります。
- そして最も重要なことは、この技術が 1980 年代に設計されたことです。今日設計されていれば、おそらくあなたが説明したものに近いでしょう。たとえば、.NET では、ターゲット アセンブリを参照するだけで、それを使用するために必要なものがすべて揃っています。
DLL のみを使用して暗黙的なリンクを行う方法を知りません。クイック検索でいくつかのツールが見つかりましたが、私はそれらのいずれも使用していません。
この場合、使用する必要がある関数を含む別のソース ファイルを作成し、必要に応じて DLL を動的にロードしてバインドします。例えば:
// using global variables and no-error handling for brevity.
HINSTANCE theDll = NULL;
typedef void (__stdcall * FooPtr)();
FooPtr pfnFoo = NULL;
INIT_ONCE initOnce;
BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context)
{
theDll = LoadLibrary();
pfnfoo = GetProcAddress(dll, "Foo");
return TRUE;
}
// Export for foo
void Foo()
{
// Use one-time init for thread-safe lazy initialization
InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL)
pfnFoo();
}