ned*_*res 5 c++ dll unresolved-external visual-studio-2012
我有一个C天文库,我想在我的C++应用程序中使用.
我在Win32和x64配置中使用Visual Studio 2012 Express构建它,并且:
...所以这是2*4 = 8个二进制文件(不包括*.pdb文件等)
然后我使用Batch Build来构建所有配置,因为有时我需要不同的版本,并且我发现在开始时完成这一切并且当一个过程很容易混合时,一个过程比偶然更好.
在我的C++应用程序中,我有相同的过程,并根据名称链接到库.具体来说,在我的项目属性链接器 - >输入字段中,我有:
SwissEphemeris_$(Platform)_$(Configuration).lib
Run Code Online (Sandbox Code Playgroud)
...并且正确设置了附加库目录.一切似乎都是对的.库文件位于库目录中.
在我拥有的8种配置中,除了两个外,所有配置都正确连接和构建:
对于这两种配置,相同的链接器错误:
main.obj : error LNK2019: unresolved external symbol _swe_close referenced in function _main
Run Code Online (Sandbox Code Playgroud)
我已经尝试了一些诊断或修复的东西,但没有一个有效:
/MACHINE链接器标志之外的偏差swe_close()在Win32动态调试配置中调用这个库函数并链接到*.lib.错误始终相同,如上所示.我已经打开了冗长的链接器输出,真正让我感到困惑的是链接器似乎成功找到并读取了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 ==========
Run Code Online (Sandbox Code Playgroud)
抓头
有没有人知道为什么链接器无法找到符号,并且只适用于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
Run Code Online (Sandbox Code Playgroud)
输出来自 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)
...
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
...然后实际的函数swe_close()声明如下:
ext_def( void ) swe_close(void);
Run Code Online (Sandbox Code Playgroud)
他们使用了很多宏步法,所以这解决了:
extern __declspec(dllexport) void far PASCAL swe_close();
我不熟悉far和PASCAL.这些会干扰什么吗?为什么x64配置可以正常工作,但Win32会破坏?
9 8 00001389 _swe_close@0 = @ILT+900(_swe_close@0)
Run Code Online (Sandbox Code Playgroud)
DLL中的函数名称与链接器正在查找的函数名称之间存在明显的不匹配.DLL项目将其编译为__stdcall函数,您可以从@ 0装饰中看出,链接器正在寻找__cdecl函数.
这可能是由编译器选项/ Gd vs/Gz引起的,但这不太可能,你已经检查过了.更可能的原因是.h文件,其中声明了导出的函数,以便另一个项目可以#include它并使用DLL.这通常是通过宏汤来完成的,因此__declspec(dllexport)和__declspec(dllimport)属性对于使用是正确的.并且应始终显式声明调用约定,通常使用另一个宏.就像Windows SDK头文件中使用WINAPI宏的方式一样.我会把汤放在原因上.
| 归档时间: |
|
| 查看次数: |
11461 次 |
| 最近记录: |