4

C ++ VisualStudio2012プロジェクトで使用したいベンダーからのdllを入手しました。ファイルが付属してい.libます。

リンクすると、次のようになります。

Error   1   error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList referenced in function "int __cdecl Ftexam(void)" (?Ftexam@@YAHXZ) C:\Users\Terry\Documents\Visual Studio 2012\Projects\Win32Project1\Win32Project1\ftexam.obj ftexample

同様の投稿を読んだことがありますが、どこにも行きません。私はそれらの答えに従ってすべてをやっていると思いますが、リンクすると未定義の参照エラーが発生します。

  1. dll.libファイルを/Linker/AddionalDependenciesリストに追加しました。
  2. dll.hファイルがソースに含まれていることを確認しました
  3. 私はdll.lib自分のプロジェクトディレクトリにファイルを置き、そこからファイルを削除すると、cannot find dll.libリンク時に取得することを確認しました(つまり、「ビルド中」です)

提供されたdll.hヘッダーファイルには、次のものがあります。

#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
.
.
#ifdef __cplusplus
extern "C" {
#endif

typedef ULONG   FT_STATUS;
.
.
DLL_API FT_STATUS FT_CreateDeviceInfoList(
    LPDWORD lpdwNumDevs
);

そして私の呼び出しコードは次のとおりです。

#include dll.h

int Ftexam(){
    FT_STATUS ftStatus=0; 
    DWORD numDevs = 0;

    // create the device information list 
    ftStatus = FT_CreateDeviceInfoList(&numDevs); 
}

おそらくいくつかの名前マングリングが行われていることに気付いたので、dependsを使用してDLLシンボルを調べました。「UndecorateC++関数」オプションが無効になっているこれらのエクスポートが一覧表示されます(つまり、これらはマングルされていないエクスポートです)。

FT_Open
FT_Close
FT_Read
....
FT_CyclePort
FT_CreateDeviceInfoList<  <<<<<this reference!!!!
FT_GetDeviceInfoList

上記で特定されたエクスポートは明らかに一致しません__imp__FT_CreateDeviceInfoList

.libファイルの定義を確認できるツール、またはVisual Studioでそれを表示する方法はありますか?

アップデート:

dumpbinを使用すると、.libのシンボルを確認できました。

__imp_FT_CreateDeviceInfoList 

instead of 

__imp__FT_CreateDeviceInfoList

これは、32ビットバージョンではなく64ビットバージョンのDLLの.libに追跡しました。(私が最初にこれを解決しようとした組み合わせの1つ)。

投稿を簡略化するために、ヘッダーに次のものが含まれていることを示しました。

DLL_API FT_STATUS FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);

When in fact, it actually contains:

DLL_API FT_STATUS WINAPI FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);

WINAPIが#definedだったので

だから変わる

#define WINAPI
to
#define WINAPI __stdcall 

正しい.libを使用すると、問題が修正されます。

4

3 に答える 3

1

VisualStudioのコマンドプロンプトを開きます。次のコマンドを実行して、libファイル内のシンボルを一覧表示します。

dumpbin / all dll.lib

出力がすぐにスクロールオフするので、上記をテキストファイルにリダイレクトします

于 2013-01-11T02:58:41.457 に答える
1

FT_CreateDeviceInfoList()は.hファイルで呼び出し規約を宣言していないため、コンパイラのデフォルトの呼び出し規約を使用します。コンパイラはデフォルトでに設定されて__cdeclいます。これは、ほとんどのC++コンパイラの通常の動作です。DLLを作成したコンパイラが、実際には代わりに別のデフォルトの呼び出し規約を使用している可能性があります。たとえば、 .hファイルを編集して指定__stdcallし、違いが生じるかどうかを確認します。例:

DLL_API FT_STATUS __stdcall FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);

ほとんどのDLLベンダーは__stdcall、C / C ++コンパイラだけでなく、幅広いコンパイラとの互換性のために使用していますが、一部のベンダーは使用してい__cdeclます__fastcall

最悪のシナリオでは、IDAやWinDASMなどの逆アセンブラを使用するか、IDE独自のデバッガを使用して、DLL内の実際のアセンブリコードを確認し、パラメータFT_CreateDeviceInfoList()にアクセスして戻り値を返すときにコールスタックをどのように管理しているかを確認できます。価値。これにより、実際に使用している呼び出し規約が正確にわかります。lpdwNumDevsFT_STATUS

更新FT_CreateDeviceInfoList():いくつかのオンライン検索を行っていると、宣言に適用された呼び出し規約を使用して呼び出す.NETコードの例がたくさんある__stdcallので、ここから始めるとよいでしょう。それが機能する場合は、DLLベンダーに連絡して、それに応じて.hファイルを修正するように依頼する必要があります。

于 2013-01-11T03:06:13.357 に答える
-1

あなたがしていることは、私が見る限りうまくいくはずです。ただし、.libファイルを忘れて、DLLを直接使用し、LoadLibraryでロードして、GetProcAddressで使用する関数のアドレスを取得することはいつでも可能です。

于 2013-01-11T01:54:51.277 に答える