バックグラウンド
C++ アプリケーションで使用したい C 天文ライブラリがあります。
Win32とx64の両方の構成で、Visual Studio 2012 Express でビルドしました。
- 動的デバッグ (.dll)
- 動的リリース (.dll)
- 静的デバッグ (.lib)
- 静的リリース (.lib)
...つまり、合計 2 * 4 = 8 個のバイナリ (*.pdb ファイルなどは数えません)
次に、バッチ ビルドを使用してすべての構成をビルドします。さまざまなバージョンが必要になる場合があり、最初にすべてを完了し、プロセスを使用する方が、混乱しやすい場合に無計画に行うよりも優れていることがわかります。
私の C++ アプリでは、同じプロセスがあり、名前に基づいてライブラリにリンクしています。具体的には、私のプロジェクト プロパティリンカ -> 入力フィールドには、次のものがあります。
SwissEphemeris_$(Platform)_$(Configuration).lib
...追加のライブラリ ディレクトリが適切に設定されています。すべてが正しいようです。ライブラリ ファイルはライブラリ ディレクトリにあります。
ここに問題があります:
私が持っている合計8つの構成のうち、2つを除いてすべてが適切にリンクおよびビルドされています。
- Win32 動的デバッグ
- Win32 動的リリース
これらの構成の両方で、同じリンカー エラー:
main.obj : error LNK2019: unresolved external symbol _swe_close referenced in function _main
診断または修正するためにいくつかのことを試みましたが、どれも機能しませんでした:
- 新しいソリューション/プロジェクトでライブラリをゼロから再構築し、リンカー フラグ以外にWin32とx64の間で逸脱がないことを確認します。
/MACHINE
swe_close()
Win32 動的デバッグ構成でこの 1 つのライブラリ関数を呼び出し、その *.lib にリンクされた main() だけを使用して、新しい新しいソリューション/プロジェクトを作成します。
上記のように、エラーは常に同じです。詳細リンカ出力をオンにしましたが、本当に困惑しているのは、リンカがファイルを正常に見つけて読み取っているように見えるのに、ファイル内のシンボルSwissEphemeris_Win32_DynamicDebug.lib
をまだ見つけられないことです。私が必要とする他のすべてのシンボルの中で、そのシンボルがその中にあることを示しているswe_close()
ときでさえ。dumpbin.exe
1> Unused libraries:
1> E:\Data\Code\lib\SwissEphemeris\SwissEphemeris_Win32_DynamicDebug.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\user32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\gdi32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\winspool.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\comdlg32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\advapi32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\shell32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\ole32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\oleaut32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\uuid.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbc32.lib
1> C:\Program Files (x86)\Windows Kits\8.0\lib\win8\um\x86\odbccp32.lib
1> E:\Programs\VS2012\VC\lib\OLDNAMES.lib
1>
1>main.obj : error LNK2019: unresolved external symbol _swe_close referenced in function _main
1>E:\Data\Code\test\Debug\test.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
頭を掻く
リンカーがシンボルを見つけられず、Win32 動的デバッグ/リリースのみで、他の 6 つの構成すべてで正常に動作する理由を知っている人はいますか?
ライブラリが実際に Win32/X86 用にビルドされていることを確認するために、ライブラリ プロジェクトのプロパティのリンカ コマンドライン オプションを次に示します。
(パスは、リンカがライブラリを見つけようとする上記のパスとは少し異なります。これは、ライブラリが最初にこの「bin」ディレクトリに構築され、次にライブラリ ディレクトリにコピーされるためです。これは確実に行われています。)
/OUT:"E:\Data\Code\libBuilders\SwissEphemeris\bin\SwissEphemeris_Win32_DynamicDebug.dll"
/MANIFEST
/NXCOMPAT
/PDB:"E:\Data\Code\libBuilders\SwissEphemeris\bin\SwissEphemeris_Win32_DynamicDebug.pdb"
/DYNAMICBASE
/IMPLIB:"E:\Data\Code\libBuilders\SwissEphemeris\bin\SwissEphemeris_Win32_DynamicDebug.lib"
/DEBUG
/DLL
/MACHINE:X86
/SAFESEH
/PGD:"E:\Data\Code\libBuilders\SwissEphemeris\bin\SwissEphemeris_Win32_DynamicDebug.pgd"
/SUBSYSTEM:CONSOLE
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"E:\Data\Code\libBuilders\SwissEphemeris\obj\SwissEphemeris_Win32_DynamicDebug\SwissEphemeris_Win32_DynamicDebug.dll.intermediate.manifest"
/ERRORREPORT:PROMPT
/NOLOGO
からの出力dumpbin.exe /exports
E:\Data\Code\lib\SwissEphemeris>dumpbin /exports SwissEphemeris_Win32_DynamicDebug.dll
Microsoft (R) COFF/PE Dumper Version 11.00.50727.1
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file SwissEphemeris_Win32_DynamicDebug.dll
File Type: DLL
Section contains the following exports for SwissEphemeris_Win32_DynamicDebug.dll
00000000 characteristics
528041A6 time date stamp Sun Nov 10 19:32:06 2013
0.00 version
1 ordinal base
131 number of functions
131 number of names
ordinal hint RVA name
1 0 00001195 _swe_azalt@40 = @ILT+400(_swe_azalt@40)
2 1 000011FE _swe_azalt_d@28 = @ILT+505(_swe_azalt_d@28)
3 2 000012AD _swe_azalt_rev@24 = @ILT+680(_swe_azalt_rev@24)
4 3 00001357 _swe_azalt_rev_d@20 = @ILT+850(_swe_azalt_rev_d@20)
5 4 0000126C _swe_calc@24 = @ILT+615(_swe_calc@24)
6 5 000011BD _swe_calc_d@20 = @ILT+440(_swe_calc_d@20)
7 6 0000105F _swe_calc_ut@24 = @ILT+90(_swe_calc_ut@24)
8 7 00001235 _swe_calc_ut_d@20 = @ILT+560(_swe_calc_ut_d@20)
9 8 00001389 _swe_close@0 = @ILT+900(_swe_close@0)
10 9 00001212 _swe_close_d@4 = @ILT+525(_swe_close_d@4)
...
ライブラリ ヘッダー ファイル内のエクスポート用に DLL が定義されている場所。MAKE_DLL
とのみPASCAL
が定義されているため、ここでアクティブなステートメントは#define PASCAL_CONV PASCAL
と#else /* 32bit DLL */
ブロックのみです。
/* DLL defines */
#ifdef MAKE_DLL
#if defined (PASCAL)
#define PASCAL_CONV PASCAL
#else
#define PASCAL_CONV
#endif
#ifdef MAKE_DLL16 /* 16bit DLL */
/* We compiled the 16bit DLL for Windows 3.x using Borland C/C++ Ver:3.x
and the -WD or -WDE compiler switch. */
#define EXP16 __export
#define EXP32
#else /* 32bit DLL */
/* To export symbols in the new DLL model of Win32, Microsoft
recommends the following approach */
#define EXP16
#define EXP32 __declspec( dllexport )
#endif
#else
#define PASCAL_CONV
#define EXP16
#define EXP32
#endif
...実際の関数swe_close()
宣言は次のようになります。
ext_def( void ) swe_close(void);
彼らは多くのマクロ フットワークを使用するため、これは次のように解決されます。
extern __declspec(dllexport) void far PASCAL swe_close();
far
とに慣れていませんPASCAL
。これらは何かに干渉している可能性がありますか? そして、なぜx64構成はこれで問題なく動作するのに、Win32は壊れるのでしょうか?