将DLL链接到Visual C时未定义的外部
我有一个想要在C Visual Studio 2012项目中使用的供应商的dll.它附带一个.lib文件.
链接时,我得到: Error 1 error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList referenced in function "int __cdecl Ftexam(void)" (?Ftexam@@YAHXZ) C:UsersTerryDocumentsVisual Studio 2012ProjectsWin32Project1Win32Project1ftexam.obj ftexample 我读过类似的帖子,但我没有到达任何地方.我想我根据这些答案做了一切,但是在链接时我仍然得到一个未定义的引用错误. >我已将dll.lib文件添加到/ Linker / Addional Dependencies列表中. 在我提供的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符号.它列出了这些导出,并禁用了“Undecorate C functions”选项(因此,这些是未解码的导出): 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 我跟踪了64位版本的DLL而不是32位版本的.lib. (我试图首先解决这个问题的组合之一). 为简化帖子,我曾指出标题包含: 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修复了问题. 解决方法
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()的实际汇编代码,并查看在访问lpdwNumDevs时如何管理调用堆栈参数并返回FT_STATUS值.这将告诉您它实际使用的确切调用约定. 更新:进行一些在线搜索,我看到很多.NET代码示例调用FT_CreateDeviceInfoList()并将__stdcall调用约定应用于其声明,因此这是一个很好的起点.如果可行,那么您应该联系DLL供应商并要求他们相应地修复他们的.h文件. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |