web-dev-qa-db-ja.com

MSVCのリンクエラーLNK2019、__ imp__接頭辞付きの未解決のシンボル、ただし静的ライブラリからのものである必要があります

MSVCで、g ++用に作成したプロジェクトのリンクの問題が発生しています。ここに問題があります:

Libsshをアプリケーションの一部として静的ライブラリとしてビルドし、cmakeでターゲットを追加します

add_library(ssh_static STATIC $ libssh_SRCS)

LibsshはCで記述されているため、c ++ソースのインクルードを「extern "C" {...}」でラップしています。次に、ssh_staticターゲットを実行可能ファイルsshconnectiontestにリンクします。

target_link_libraries(sshconnectiontest ... ssh_static ...)

これはすべてLinuxのgccで問題なく動作しますが、現在MSVCでは

error LNK2019: unresolved external symbol __imp__[function names here] referenced in [filename]

私が使用するすべてのlibssh関数に対して。

どんなアイデアが間違っているのですか? imp接頭辞がリンカが.dllをリンクすることを期待していることを意味することをどこかで読んだことがありますが、ssh_staticはadd_library呼び出しで静的ライブラリとして宣言されているため、これは当てはまりません...

26
dlonie

私のWindows時代を思い出して、MinGWでビルドされたDLLでは、___imp___シンボルプレフィックスは、DLL properを呼び出すトランポリン関数に使用されます。このシンボルは、次に提供されます。拡張子が_.dll.a_の小さな静的ライブラリ。

Libsshヘッダーを含める場合は、_#define_を設定して、静的にリンクすることを期待していることを示す必要があります。そうしないと、ヘッダーのlibssh関数は__declspec(dllimport)として宣言されるため、リンク時に___imp___シンボルが期待されます。

私はlibsshのソースを見て、これが_libssh.h_の上部にあるのを見つけました:

_#ifdef LIBSSH_STATIC
  #define LIBSSH_API
#else
  #if defined _WIN32 || defined __CYGWIN__
    #ifdef LIBSSH_EXPORTS
      #ifdef __GNUC__
        #define LIBSSH_API __attribute__((dllexport))
      #else
        #define LIBSSH_API __declspec(dllexport)
      #endif
    #else
      #ifdef __GNUC__
        #define LIBSSH_API __attribute__((dllimport))
      #else
        #define LIBSSH_API __declspec(dllimport)
      #endif
    #endif
  #else
    #if __GNUC__ >= 4
      #define LIBSSH_API __attribute__((visibility("default")))
    #else
      #define LIBSSH_API
    #endif
  #endif
#endif
_

_LIBSSH_STATIC_を_#define_行の前の_#include <libssh.h>_を通じて、または_/D_オプションとして定義する必要があります。 CMakeを使用しているので、おそらく_add_definitions_の_CMakeLists.txt_を使用してこれを実行します。

28
Jack Kelly

それがあなたのケースであるかどうかはわかりませんが、impプレフィックスは、Win32プロジェクトでx64ライブラリをコンパイルしていることを意味する場合があります。

13
Ago

パーティーには多少遅れましたが、CRTへの静的リンクと動的リンクのライブラリを混在させると、同じエラーが発生しました

1
kreuzerkrieg

。DEFファイルの使用

__declspec(dllimport)を.DEFファイルとともに使用する場合は、.DEFファイルを変更してDATAまたはCONSTANTを使用し、誤ったコーディングが問題を引き起こす可能性を減らします。

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   CONSTANT

次の表に理由を示します。

Keyword      Emits in the import library   Exports
CONSTANT     _imp_ulDataInDll              _ulDataInDll
             _ulDataInDll                  

DATA         _imp_ulDataInDll              _ulDataInDll

http://msdn.Microsoft.com/en-us/library/aa271769(v = vs.60).aspx

[〜#〜] but [〜#〜]CONSTANTは廃止されました

私は別の方法を見つけました、エクスポートされた.libの.DEFファイルで使用:

 mainthreadid=_mainthreadid

lIB.exeでlibを再生成します

dLLコードのインポートヘッダーファイルで...

extern "C" {
  extern const __declspec(dllexport) ulong mainthreadid;
}
0
Tanguy