__declspec(dllimport)はどういう意味ですか?


91

私はこのようなQtソースコードを見ました:

class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};

これはQ_CORE_EXPORT以下のようなマクロ定義しています。

define Q_DECL_IMPORT __declspec(dllimport)

それで、どういう__declspec(dllimport)意味ですか?


回答:


118

__declspecストレージクラス情報を指定できるMicrosoft固有の属性です。
(Nitpickerのコーナー:ただし、他の多くのコンパイラベンダー(GCCなど)は、Microsoftのコンパイラを対象として記述されたインストール済みのコードベースとの互換性のために、この言語拡張をサポートしています。追加のストレージクラス属性を提供するものさえあります。)

指定できる2つのストレージクラス属性はdllimport、およびdllexportです。これらは、DLLから関数またはオブジェクトが(それぞれ)インポートまたはエクスポートされることをコンパイラーに示します。

より具体的には、モジュール定義(.DEF)ファイルを必要とせずに、クライアントへのDLLのインターフェースを定義します。ほとんどの人は、DEFファイルを作成するよりも、これらの言語拡張を使用する方がはるかに簡単だと感じています。

明白な理由で、__declspec(dllimport)そして__declspec(dllexport)一般的に互いにペアになっています。を使用dllexportして、DLLからエクスポートされたシンボルをマークし、dllimportそのエクスポートされたシンボルを別のファイルにインポートします。

このため、またDLLのコンパイル時とDLLのインターフェイスを使用するクライアントコードの両方で同じヘッダーファイルが一般的に使用されるため、コンパイル時に適切な属性指定子に自動的に解決されるマクロを定義するのが一般的なパターンです。例えば:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

次に、エクスポートする必要があるすべてのシンボルをでマークしDLLEXPORTます。

おそらく、それがQ_CORE_EXPORTマクロが行うことで、Q_DECL_IMPORTまたはのいずれかに解決されますQ_DECL_EXPORT


__declspecは適切に「MS固有」ではなく(より「コンパイラ固有」です)、一部のコンパイラは複数のプラットフォームでもこの宣言を使用します。一部の属性値は(dllexport / dllimportsはMS固有です。DLLはMSなのでレキシコン)
エミリオガラヴァリア2012年

9
@エミリオ:私の知る限り、マイクロソフト__declspecはC ++言語の拡張機能としてこの表記法を発明しました。GCCは現在これをサポートしていると思いますが、これは主にマイクロソフトのコンパイラとの互換性の理由によるものです。「MS固有」と「コンパイラ固有」の違いがわかりません。マイクロソフトはC ++コンパイラを作成し、多くの人がそれを使用しています。Visual Studioに付属しています。
コーディグレイ

8
マイクロソフトはコンパイラを作成します。「Microsoft C / C ++ Optimizing Compiler」と呼ばれるcl.exeです。多くの人々は、Visual Studioをコンパイラーであるかのように誤って参照していますが、これはIDEです。「Microsoft固有」の意味について人々が何を言っているのかわかりません。「MS環境」(それが何であれ)を意味するものではなく、「Windows」を意味するものでもありません。はい。他のコンパイラベンダーは、Microsoftコンパイラを対象として記述されたインストール済みコードベースとの互換性のための拡張機能をサポートしています。前に言ったように、私が知る限り、Microsoftが構文を発明しました。それがここでのポイントです。
コーディグレイ

2
@CodyGray:マイクロソフトだけで発明しただけでは不十分です。ただし、 Microsoftが発明し、それを含む標準はなく、互換性のためにのみ実装し、Microsoft Windowsを対象とするプログラムで主に(排他的ではないにせよ)使用されているため、これを「Microsoft固有」と呼ぶのは非常に強力です
celtschk

6
これは素晴らしい回答です。特に、「DLLのコンパイル時とクライアントコードの両方で同じヘッダーファイルが一般的に使用されるため」に関する部分です。インポート/エクスポートのもののすべての側面を明確にします。
Ela782 2014

30

__declspec(dllimport) 関数、オブジェクト、またはデータ型が外部DLLで定義されていることをコンパイラに通知するストレージクラス指定子です。

関数、オブジェクト、またはデータ型は、対応すると共にDLLからエクスポートされます__declspec(dllexport)


6
OK。最後に、2時間読んだ後、私は最も満足のいく、最も簡潔で、自分が欲しいもののポイントステートメントに正確であることがわかりました。
el psy Congroo

1

__declspec(dllexport)これらのシンボルをエクスポートテーブルに配置する必要があることをリンカーに通知するようコンパイラーに指示します(.dllのコンパイル時)。.dllとリンクするプログラムをコンパイルするときに、通常のリップ相対レジスター直接ではなく__declspec(dllimport)、リップ相対絶対レジスター間接間接呼び出し(リンカーがインポートテーブルを指すように解決を埋める)を生成するようコンパイラーに指示します。未定義の関数への間接呼び出し命令(命令を変更できないため、リンカーはサンクの相対アドレスを挿入し、サンクを作成します。その内部に、rip相対絶対レジスター間接呼び出しを配置し​​ます。インポートテーブルの関数ポインタ)。これはコードサイズと速度の最適化です。どのシンボルがインポートされるかをリンカーに指示するインポートライブラリ.libは、インポートテーブルを作成し、.textセグメントに必要なサンクを作成するためのガイドとして使用されます。

https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-declspec-dllimport?view = vs-2019 https://stackoverflow.com/a/4490536/7194773


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.