加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

将DLL链接到Visual C时未定义的外部

发布时间:2020-12-14 05:41:50 所属栏目:Windows 来源:网络整理
导读:我有一个想要在C Visual Studio 2012项目中使用的供应商的dll.它附带一个.lib文件. 链接时,我得到: Error 1 error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList referenced in function "int __cdecl Ftexam(void)" (?Ftexam@@YAHX
我有一个想要在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文件包含在我的源代码中
>我已将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符号.它列出了这些导出,并禁用了“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文件.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读