5

私は必死にあなたの助けが必要です。

Visual C ++ 2008コンパイラを使用してWindowsでpopplerライブラリ(特にqt4用)を静的にコンパイルしようとしています。このタスクを実行するには、popplerの依存関係として他のライブラリも静的にコンパイルする必要がありました。静的バージョンのpopplerを最終的に生成すると、アプリのビルド時にリンクエラーが発生しました。

error LNK2019: unresolved external symbol "__declspec(dllimport)...

私はすでに新しいインクルードパスを追加し、poppler-qt4.libをリンクしましたが、とにかくエラーが発生します。解決策を探している私はこの議論をstackoverflowで見つけました

Visual C ++ 2008で静的ライブラリをリンクするにはどうすればよいですか?

この情報を見て、ライブラリのインクルードファイル(zlib、libpng、cairoなどのpopplerの依存関係)を調べたところ、さまざまなケースで、静的バージョンを指定するためのプリプロセッサディレクティブがないことがわかりました。 lib。静的ディレクティブの例(openjpeg.h):

#if defined(OPJ_STATIC) || !(defined(_WIN32) || defined(WIN32) || defined(__WIN32__))
# define OPJ_API
# define OPJ_CALLCONV
#else
# define OPJ_CALLCONV __stdcall
# ifdef OPJ_EXPORTS
#  define OPJ_API __declspec(dllexport)
# else
#  define OPJ_API __declspec(dllimport)
# endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !WIN32 */

静的ディレクティブのない例(jpeg libのjconfig.h):

#if defined(_WIN32)
    #if defined(libjpeg_EXPORTS)
        #define JPEG_EXPORT __declspec(dllexport)
    #else
        #define JPEG_EXPORT __declspec(dllimport)
    #endif
#else
    #define JPEG_EXPORT 
#endif

私の質問は、プロジェクトのプロパティを動的から静的に変更するだけでは不十分なので、このヘッダーも変更する必要がありますか?これが当てはまる場合、静的コンパイルと動的コンパイルを区別するためのこの新しいディレクティブをどこで定義できますか? ?

前もって感謝します。

4

2 に答える 2

4

まず、Windows には動的リンケージがまったくないことに注意してください。サプライズ!代わりに、サンクを使用します。つまり、シンボル dllexport を作成すると、その実際の名前は、dllexport ではない場合と同じ名前になります。ただし、オブジェクト ファイルではエクスポート用にマークされています。

一方、dllimport と言うと、C では大まかに名前の前に __imp_ を追加して名前が変更されますが、C++ ではさらに厄介です。

さて、DLL をリンクすると、(もちろん) DLL が取得されますが、LIB ファイルも取得されます。それがスタティック リンク ライブラリです。リンカーが処理できる唯一の種類です。DLL からエクスポートされたシンボルごとに、その LIB ファイルに dllimport シンボルがあり、特に __imp_ プレフィックスまたは C++ 用のものがあります。

したがって、プログラムまたは DLL で、その DLL にリンクする必要がある場合は、代わりにインポート LIB に対してリンクします。インポート LIB ルーチンは、DLL からの実際のロード時のアドレスにパッチを適用するサンクです。

したがって、dllexport を含む OBJ ファイルを単純に組み合わせて LIB.EXE によって作成された LIB ファイルに対して通常の静的リンクを実行しようとすると、参照が dllimport である場合に失敗します。ライブラリに実際にプレーンな function() が含まれているときに __imp_function() を参照しているためです。

したがって、静的リンケージでは、dllimport を削除する必要があります。AFAIK dllexport は無関係です。これは、ライブラリ自体ではなく、ライブラリのクライアントに適用されることに注意してください。

どういう意味ですか?ライブラリに静的にリンクし、別のライブラリに動的にリンクすることはまったく問題ありません。実際、Windows の既定の静的リンクは、C ランタイムと OS DLL に動的にリンクします。したがって、ルールは次のとおりです。クライアントはライブラリにリンクする方法を選択する必要があり、プロバイダーは両方のバージョンを提供する必要があります。でも名前が違うので注意!!(そうしないと、DLL を作成する LINK が fred.LIB を作成し、LIB も fred.LIB を作成します)

于 2015-09-12T04:47:50.017 に答える
2

プロジェクト プロパティを openjpeg.h で指定されているように動的リンクから静的リンクに変更する場合は、静的リンクを使用できるプリプロセッサを指定する必要があります。そのため、プロパティを動的から静的に変更するだけでなく、プリプロセッサ OPJ_STATIC を追加します。 .

例えば:

#if defined(_WIN32)
    #if defined(OPJ_STATIC)
         # define OPJ_CALLCONV __stdcall
    #el if defined(libjpeg_EXPORTS)
        #define JPEG_EXPORT __declspec(dllexport)
    #else
        #define JPEG_EXPORT __declspec(dllimport)
    #endif
#else
    #define JPEG_EXPORT 
#endif
于 2011-01-30T07:39:49.743 に答える