1

明確にするために: 以下の例が dll 依存性を示していることは承知しています。つまり、1 つのライブラリは自己完結型ではなく、機能するために別のライブラリに依存しています。

一般的な性質のさまざまな便利な関数を含むランタイム ライブラリ Utility.dll を作成しているとします。Utility.dll を使用する必要がある他のファイルに含まれるヘッダー ファイル Utility.h を作成します。ヘッダーファイルは次のようになります

#ifndef _UTILITY_H
#define _UTILITY_H

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

DLL_EXPORT void foo();
DLL_EXPORT void foo2();
....

#endif

ソース コード ファイル Utility.cpp をマシン コード (Utility.dll) にコンパイルするときに、BUILD_DLL が定義されていることを確認して、DLL_EXPORT が __declspec(dllexport) に置き換えられるようにします。これにより、関数が .dll ファイルにエクスポートされます。ヘッダー Utility.h をインクルードし、インポート ライブラリ (MS VS の場合は Utility.lib、g++ の場合は libUtility.a) とリンクし、BUILD_DLL を定義しないと、Utility.h の関数宣言は代わりに __declspec(dllimport) で始まり、関数が .dll からインポートされるコンパイラ (いわば)。

ここで、別のライブラリ MyLibrary.dll も構築しているとします。このライブラリは、Utility.dll の便利な関数の一部を使用したいと考えています。同様に、MyLibrary.h を次のように作成します。

#ifndef _MYLIBRARY_H
#define _MYLIBRARY_H

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

DLL_EXPORT void myLibraryFunc1();
....

#endif

MyLibrary.cpp を MyLibrary.dll にコンパイルすると、Utility.h がインクルードされ、Utility インポート ライブラリにもリンクされます。

これは私の質問につながります: MyLibrary.dll をコンパイルするときに BUILD_DLL も定義するので、これは Utility.h の関数宣言も読み取ることを意味します。

__declspec(dllexport) void foo();
__declspec(dllexport) void foo2();
....

いいえ

__declspec(dllimport) void foo();
__declspec(dllimport) void foo2();

MyLibrary.dll をコンパイルするときに、Utility.h の関数宣言を __declspec(dllimport)、MyLibrary.h の関数宣言を __declspec(dllexport) にしたくないですか?

4

1 に答える 1

2

これがまさに、通常、そのようなマクロに名前を付けない理由ですBUILD_DLLBUILD_UTILITYBUILD_MYLIBRARYまたは同様のものです。同様に、declspec マクロはDLL_EXPORT, but UTILITY_EXPORTand MYLIBRARY_EXPORT(またはおそらくUTILITY_APIand MYLIBRARY_API) であってはなりません。

于 2015-07-09T19:36:13.360 に答える