0

ランタイムリンク用にいくつかのWinApiを使用Loadlibraryしてリンクしました。Getprocaddress期待どおり、正常に動作します。

しかし、一部のApiでは-ldllname、コンパイラオプションとして使用しました。同じオプションを使用すると、一部のAPIでリンカーエラーが発生し、dllをロードする必要があります。

これに特別な違いはありますか?つまり、特定のAPIにはランタイムリンクが必要であり、他のAPIは-ldllnameオプションで動作しますか?これらの種類のAPIを分類する方法は?

更新:私が観察したのは、UNICODEとANSIをサポートするAPIです。つまり、「W」と「A」の接尾辞が付いたAPIは、静的リンク自体で解決されますか?私は正しいですか?私が間違っている場合は私を訂正してください!

一部のAPIがランタイムリンクを必要とし、他のAPIが静的リンク自体(-lオプション)で解決されるのはなぜですか?これには何か理由がありますか?

4

2 に答える 2

1

それは本質的にあなたが説明したものです。ここでは Windows 以外はスキップしますが、基本的には同様です)。

したがって、2 つの異なるケースがあります。

コンパイル時 (静的) リンク:コードにはすべての関数、クラスなどの宣言が含まれますが、本体は含まれません。コンパイル時に適切なライブラリ ファイルを提供する必要があります (例: を介して-ldllname)。

void sayHello(void); // the declaration might be a bit more complicated, e.g. adding a calling convention or dllimport/dllexport, etc.

ランタイム (動的) リンク:コードには、基本的にライブラリをロードし、アドレスを取得する (指定した関数を介して) 最小限の関数本体が含まれます。

HMODULE lib = LoadLibrary("hello.dll"); // loading happening somewhere once

void sayHello(void) {
    myfnproc call = GetProcAddress(lib, "sayHello");
    call(); // actual call
}

FreeLibrary(lib); // unloading happening somewhere else

ランタイム アプローチはより複雑ですが、大きな利点が 1 つあります。不足しているライブラリを処理できるということです。たとえば、ユーザーにライブラリが不足している場合、どこからダウンロードするか (または自分でダウンロードすることもできます)、リンクされたコードを簡単に置き換えることができます (プラグイン機能など)。静的リンクを使用すると、運が悪くなります。依存関係が欠落している場合、プログラムは実行されません。

于 2012-08-16T08:39:28.707 に答える
1

ロードライブラリを使用しました

これは、DLL に暗黙的に依存する例です。LoadLibrary は、Windows API DLL である kernel32.dll によってエクスポートされる関数です。実際には、LoadLibraryA と LoadLibraryW の 2 つのバージョンが存在します。それぞれ、関数の非 Unicode バージョンと Unicode バージョンです。コンパイル時に UNICODE マクロが #defined であるかどうかに応じて、どちらかが得られます。

これは、GetProcAddress を使用してエクスポートを動的にリンクするのとは正反対です。リンカーに、-lオプションを使用して、プログラムが kernel32 に依存していることを伝える必要があります。また、実行時に、独自のコードが実行を開始する前に、DLL が自動的に読み込まれます。

オペレーティング システムの DLL に暗黙的に依存することは、ごく普通のことです。そして避けられないのは、kernel32.dll を動的にリンクすることは決してできないということです。これは鶏が先か卵が先かの問題です。

于 2012-08-16T09:29:26.973 に答える