4

私は、DLL 関数を静的にインポートするのが非常に簡単な Delphi の世界から来ました。関数名とモジュールを次のように指定するだけです。

function GetTickCount : DWORD; stdcall; external 'Kernel32.dll';

kernel32.lib関数をインポートするためにC++で使用する必要があるのはなぜですか? Delphi と同じように、リンカにその関数をインポートするように単純に指示できないのはなぜですか?

多くの人にとって、それはばかげているように聞こえるかもしれませんが、Delphi から C++ の世界に入ると、本当に混乱する可能性があります。

4

3 に答える 3

8

C++ ツールチェーンは、Delphi が 1 つのステップで実行できることを実行するために、いくつかのステップを実行します。C++ で外部 DLL 関数を宣言する場合、その関数が実際にどの名前付き DLL に含まれているかを示す (標準的な) 方法はexternありません。リンカーによってどこかで見つかります。

名前付き関数をその関数が含まれる DLL に接続するために、C++ ツールチェーンには、リンカが何をすべきかを認識しているインポート スタブを含む "インポート ライブラリ" が必要です。インポート スタブによって定義された関数を見つけると、リンカーは、対応する DLL 内の特定の関数名に対する DLL 関数参照を作成します (インポート スタブによって示されます)。

Delphi では、言語設計者は、プログラマが関連する DLL をソース コードで直接指定できるようにしていました。その後、Delphi コンパイラは、インポート スタブの手順を使用せずに、外部 DLL への参照を直接生成できます。

于 2012-10-12T06:44:30.803 に答える
4

あなたの質問は、シンボル (つまり、関数名) を DLL 内の関数の序数にバインドするための中間ステップとして「インポート ライブラリ」を使用する必要がある Microsoft C++ コンパイラ (MSVC) の問題だけです。それ自体は C++ の問題ではありません。これは間違いなく、MSVC コンパイラの厄介な癖の 1 つにすぎませんが、そのようなスキームを変更する必要があるかどうか、または変更できるかどうかについてコメントする動機については十分に知りません。私の記憶が正しければ、C++Builder コンパイラもこのメカニズムで動作し、MSVC を模倣しています。

他のほとんどのコンパイラは、リンクとバイナリ インターフェイスに関して、GCC の動作方法 (GNU Compiler Collection) に合わせています。そして、それらはこの追加の「インポートライブラリ」を必要とせず、問題のDLLをライブラリの一部として指定して、実行可能ファイルとリンクするだけです。

ところで、C++ リンカと Delphi リンカの違いに関して言えば、あなたが指摘したこの問題は氷山の一角にすぎません。それらは、より深い意味で非常に異なっています。C++ 標準では、リンカは (「個別コンパイル モデル」のため) かなり単純であり、いわばドットを接続するだけである必要がありますが、Delphi では、リンカはコンパイラとより密接にリンクされており、一般的によりスマートです (そして、もっと早く)。

于 2012-10-12T07:05:24.240 に答える
1

次の機能リクエストをQCに送信しました。

QC#109493:.libファイルのインポートを必要とせずにDLL関数をインポートするためのコンパイラ拡張機能を追加します

于 2012-10-13T01:05:38.913 に答える