将DLL链接到Visual C++时未定义的外部链接
我从我想在C++ Visual Studio 2012项目中使用的供应商那里获得了一个dll。它带有一个.lib
文件。将DLL链接到Visual C++时未定义的外部链接
链接时,我得到:
Error 1 error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList referenced in function "int __cdecl Ftexam(void)" ([email protected]@YAHXZ) C:\Users\Terry\Documents\Visual Studio 2012\Projects\Win32Project1\Win32Project1\ftexam.obj ftexample
我读过类似的职位,但我没有得到任何地方。我想我正在根据这些答案做所有事情,但链接时仍然会出现未定义的参考错误。
- 我已将dll.lib文件添加到/ Linker/Addional Dependencies列表中。
- 我已经取得了一定的dll.h文件包含在我的源
- 我已经把
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符号。它列出了这些出口的“去除装饰C++功能”选项被禁用,(所以,这些都是未重整出口):
FT_Open
FT_Close
FT_Read
....
FT_CyclePort
FT_CreateDeviceInfoList< <<<<<this reference!!!!
FT_GetDeviceInfoList
标识的出口上面明显不符__imp__FT_CreateDeviceInfoList
是否有一个工具周围可以查看.lib文件中的定义,还是以某种方式让visual studio显示它?
UPDATE:
通过使用DUMPBIN的我能看到的.lib符号是
__imp_FT_CreateDeviceInfoList
instead of
__imp__FT_CreateDeviceInfoList
这个我跟踪到的.lib为DLL的64位版本,而不是的32位版本。 (我试图首先解决这个问题的组合之一)。
为了简化后,我已表示,标头包含:
DLL_API FT_STATUS FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);
When in fact, it actually contains:
DLL_API FT_STATUS WINAPI FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);
因为WINAPI被#define的
因此更改
#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
值。这将告诉你它究竟使用哪种调用约定。
UPDATE:做一些网上搜索,我看到应用于其声明调用FT_CreateDeviceInfoList()
与__stdcall
调用约定的.NET代码例子很多,所以这是开始的好地方。如果有效,那么你应该联系DLL供应商,并要求他们相应地修复他们的.h文件。
谢谢。通过使用dumpbin,我可以看到.lib中的符号是__imp_FT_CreateDeviceInfoList vs __imp__FT_CreateDeviceInfoList。我跟踪了这一点,以引用64位版本的.lib而不是32位版本。 – user1967890
你在做什么应该尽我所能地工作。但是你总是可以忘记.lib文件并直接使用该DLL,使用LoadLibrary加载它并获取要用于GetProcAddress的函数的地址。
打开Visual Studio命令提示符。火以下命令列出的符号在lib文件:
DUMPBIN /所有dll.lib
重定向以上到一个文本文件,作为输出滚出迅速
WINAPI应该已经被Windows正确定义。我承认你正在使用的图书馆,目前正在使用它,而无需修改。在包含库头之前,您是否“#include”? –