将DLL链接到Visual C++; 我从一个供应商中得到了一个DLL,我想在C++ Visual Studio 2012项目中使用它。它附带一个.lib文件
当我得到:将DLL链接到Visual C++; 我从一个供应商中得到了一个DLL,我想在C++ Visual Studio 2012项目中使用它。它附带一个.lib文件,c++,dll,visual-studio-2012,C++,Dll,Visual Studio 2012,当我得到: 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
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
我也读过类似的帖子,但我一无所获。我想我做的一切都是根据这些答案,但我仍然会在链接时遇到一个未定义的引用错误
dll.lib
文件放入了我的项目目录中,并确保如果我将其从那里删除,我在链接时会发现找不到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++函数”选项禁用,(因此,这些是未加密的出口):
我跟踪到64位版本的DLL的.lib,而不是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 WINAPI
to
#define WINAPI __stdcall
除了使用正确的.lib之外,还解决了这个问题。就我所知,您所做的应该是可行的。但是,您总是可以忘记.lib文件,直接使用DLL,使用LoadLibrary加载它,并获取要使用GetProcAddress的函数的地址。打开Visual Studio命令提示符。触发以下命令以列出lib文件中的符号: dumpbin/all dll.lib
将上面的内容重定向到文本文件,因为输出会快速滚动
FT\u createDeviceInfo()
没有在.h文件中声明任何调用约定,因此它使用编译器的默认调用约定。您的编译器默认为< C++ >代码> >代码>,这是大多数C++编译器的正常行为。很可能创建DLL的编译器实际上使用了不同的默认调用约定。例如,尝试编辑.h文件以指定\uu stdcall
,并查看它是否有任何区别,例如:
DLL_API FT_STATUS __stdcall FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);
大多数DLL供应商使用\uuu stdcall
与最广泛的编译器兼容,而不仅仅是C/C++编译器,尽管有些供应商确实使用\uuuu cdecl
甚至\uu fastcall
(不同的编译器供应商实现了不同的编译器,因此请注意这一点)
更糟糕的情况是,您可以使用反汇编程序,如IDA或WinDASM,或者只使用IDE自己的调试器,查看DLL中FT\u CreateDeviceInfo()
的实际汇编代码,并查看它在访问lpdwNumDevs
参数并返回FT\u STATUS
值时如何管理调用堆栈。这将准确地告诉您它实际使用的调用约定
更新:在进行一些在线搜索时,我看到许多.NET代码示例调用
FT\u createDeviceInfo()
,并将\u stdcall
调用约定应用于其声明,因此这是一个很好的起点。如果这样做有效,那么您应该联系DLL供应商,要求他们相应地修复其.h文件。谢谢。通过使用dumpbin,我可以看到.lib中的符号是uu imp\u FT\u createDeviceInfo列表vs uu imp\uu FT\u createDeviceInfo列表。我跟踪到引用了64位版本的.lib,而不是32位版本。Windows应该已经正确定义了WINAPI。我知道你正在使用的库,目前我自己也在使用,没有修改。在包含库标题之前是否包含“#include”?
#define WINAPI
to
#define WINAPI __stdcall
DLL_API FT_STATUS __stdcall FT_CreateDeviceInfoList(LPDWORD lpdwNumDevs);