VC引入lib库并解决连接错误unresolved external symbol "__declspec(dllimport) const DllClass::`vftable'" (__imp_?

本文介绍了在Visual C++环境中引入lib库的三种方法,并详细解释了如何通过这些方法使用静态链接库和动态链接库。此外,还提供了解决编译过程中出现的未解析外部符号错误的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

VC中引入lib库:

链接库分为静态链接库和动态链接库,静态链接库只有一个.lib文件,而动态链接库则有一个.lib文件和.dll文件;静态链接库的.lib文件里面有函数真正实现的机器码,而动态链接库的.lib只有函数的符号名,真正的函数的实现在dll文件中。

当你使用静态库或者使用隐式的方式加载动态连接库的话,都需要将.lib文件加到vc工程里面去,他们的区别就在于,使用动态库的话,在运行程序时,需要额外将函数真正实现的dll文件放到程序的运行目录下或者程序默认的搜索路径下,而静态库则只要引入.lib文件后,就可以调用库中的函数。

在vc环境下将lib库引入工程,有下面3种方法:

第一种方法,lib文件直接加入到工程文件列表中。

在VC中打开“File View”一页,选中工程名,单击鼠标右键,然后在弹出的快捷菜单中选择【Add Files to Project】命令,在弹出的文件对话框中选中要加入dll的lib文件即可。


第二种方法,设置工程的【Project】菜单【Settings】来加载dll的lib文件

打开工程的【Project】菜单的【Settings】,选中【Link】,然后在“Object/library modules”下的文本框中输入dll的lib文件。

第三种方法,预编译指令导入

加入预编译指令#pragma comment(lib,”*.lib”),这种方法优点是可以利用条件预编译指令链接不同版本的lib文件。因为,在Debug方式下,产生的lib文件是Debug版本,如Regd.lib;在Release方式下,产生的lib文件时Release版本,如Regr.lib。

当然,在引入.lib文件后,工作并没有完成,为了解决编译问题,我们还需要将连接库中函数的对应的头文件(*.h)包含到其中,在这个头文件中给出了链接库中定义的函数原型。在编译完成后,连接器会去.lib文件中去查找函数的符号表,找到后,编译和连接工作就完成了;在运行的时候,再去dll文件中去找函数的真正实现(如果是静态库则直接在.lib文件中寻找函数的真正实现。)

转自:http://www.cnblogs.com/RascallySnake/archive/2012/10/17/2728557.html

解决VC6.0中的连接错误:

在涉及到进程信息获取部分中,需要使用Psapi.lib和psapi.h,在VC6.0中并不包含该类库,需要额外下载,将Psapi.lib放入VC安装目录下的LIB,将psapi.h放入INCLUDE,Psapi.dll一般系统自带,位于System32目录下。

在这里实现的是将dll注入到一个进程的地址空间,在VC6.0中需要自己设置一些选项,添加lib等链接库,程序才能正常编译生成。

添加链接库利用上述提到的方法即可,在连接中还是产生了如下错误:

unresolved external symbol "__declspec(dllimport) const DllClass::`vftable'" (__imp_??_7DllClass@@6B@)

这里的解决方法是没有将头文件中的预处理定义加入设置,

在VC工程的工程->设置->C/C++->预处理程序定义中添加BUILDING_DLL即可。

错误原因详细分析:点击打开链接

参考:http://blog.chinaunix.net/uid-25958655-id-4194184.html



1>Misc.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z) 21:13:14:191 1>AiManager.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z) 21:13:14:191 1>CBuffManager.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z) 21:13:14:191 1>CObject.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z) 21:13:14:191 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z) 21:13:14:191 1>Misc.obj : error LNK2001: 无法解析的外部符号 atexit 21:13:14:191 1>ShellCode.obj : error LNK2001: 无法解析的外部符号 atexit 21:13:14:191 1>AiManager.obj : error LNK2001: 无法解析的外部符号 atexit 21:13:14:191 1>CBuffManager.obj : error LNK2001: 无法解析的外部符号 atexit 21:13:14:191 1>CObject.obj : error LNK2001: 无法解析的外部符号 atexit 21:13:14:191 1>dllmain.obj : error LNK2001: 无法解析的外部符号 atexit 21:13:14:191 1>CBuffManager.obj : error LNK2001: 无法解析的外部符号 _fltused 21:13:14:191 1>dllmain.obj : error LNK2001: 无法解析的外部符号 _fltused 21:13:14:203 1>Misc.obj : error LNK2001: 无法解析的外部符号 _fltused 21:13:14:203 1>Vector.obj : error LNK2001: 无法解析的外部符号 _fltused 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "void * __cdecl operator new(unsigned __int64)" (??2@YAPEAX_K@Z) 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "void * __cdecl operator new[](unsigned __int64)" (??_U@YAPEAX_K@Z) 21:13:14:203 1>ShellCode.obj : error LNK2001: 无法解析的外部符号 "void * __cdecl operator new[](unsigned __int64)" (??_U@YAPEAX_K@Z) 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete[](void *)" (??_V@YAXPEAX@Z) 21:13:14:203 1>ShellCode.obj : error LNK2001: 无法解析的外部符号 "void __cdecl operator delete[](void *)" (??_V@YAXPEAX@Z) 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 _Init_thread_header 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 _Init_thread_footer 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 __imp_GetAsyncKeyState 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 __imp_GetForegroundWindow 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "void __cdecl std::_Xlength_error(char const *)" (?_Xlength_error@std@@YAXPEBD@Z) 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 __chkstk 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 _Init_thread_epoch 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "__declspec(dllimport) void (__cdecl* std::_Raise_handler)(class stdext::exception const &)" (__imp_?_Raise_handler@std@@3P6AXAEBVexception@stdext@@@ZEA) 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 "const type_info::`vftable'" (??_7type_info@@6B@) 21:13:14:203 1>dllmain.obj : error LNK2001: 无法解析的外部符号 _tls_index 21:13:14:203 1>D:\WeGameApps\英雄联盟\Game\hid.dll : fatal error LNK1120: 16 个无法解析的外部命令
最新发布
08-08
<think>我们正在处理多个LNK2001链接错误,这些错误表明链接器找不到某些外部符号的定义。这些符号包括C++运行时函数、Windows API函数以及CRT函数。根据引用[1]和引用[2],这类问题通常是由于文件未正确链接或项目设置问题导致的。 首先,我们列出用户提到的所有未解析符号: 1. operator delete 2. atexit 3. _fltused 4. GetAsyncKeyState 5. GetForegroundWindow 6. std::_Xlength_error 7. __chkstk 8. type_info 9. vftable 10. tls_index 这些符号可以分为几类: 1. C++运行时函数(如operator delete, atexit, std::_Xlength_error, type_info, vftable) 2. Windows API函数(如GetAsyncKeyState, GetForegroundWindow) 3. 编译器内部函数(如__chkstk, _fltused, tls_index) 解决步骤: ### 1. 检查链接和项目设置 - **C++运行时**:确保项目设置中运行时的选择正确且一致。例如,如果使用静态链接(/MT或/MTd),则所有都应使用相同的设置;如果使用动态链接(/MD或/MDd),则同样要一致。不一致会导致链接错误[^1]。 - 在Visual Studio中,检查项目属性 -> C/C++ -> 代码生成 -> 运行时。 - **Windows SDK**:对于Windows API函数(如GetAsyncKeyState, GetForegroundWindow),需要链接`user32.lib`。在项目属性 -> 链接器 -> 输入 -> 附加依赖项中添加`user32.lib`。 ### 2. 检查缺失的 - **C++标准**:确保链接了正确的C++标准。根据运行时设置,可能是`libcmt.lib`(静态)或`msvcrt.lib`(动态)等。但通常不需要手动添加,除非项目设置有问题。 - **编译器运行时**:对于`__chkstk`、`_fltused`等,它们通常在编译器提供的中(如`libcmt.lib`、`libvcruntime.lib`)。确保这些被链接。 ### 3. 特殊符号的处理 - **vftable**:这是C++虚函数表,通常由编译器自动生成。如果出现未解析,可能是由于类声明了虚函数但没有定义(或者定义在未链接的中)。 - **type_info**:与RTTI相关,确保项目设置中启用了RTTI(项目属性 -> C/C++ -> 语言 -> 启用RTTI)。 - **tls_index**:与线程本地存储相关,通常由编译器内部处理,但需要确保链接了相应的运行时。 ### 4. 检查函数声明与定义 - 确保所有函数都有定义(包括在中)。例如,`operator delete`是C++运行时的一部分,如果项目中没有定义,必须链接运行时。 ### 5. 针对引用[1]中类似问题的解决 引用[1]提到,在链接静态时出现未解析符号`__imp___std_init_once_begin_initialize`等。这是因为静态在编译时使用了动态链接运行时(/MD),而主项目使用了静态链接(/MT)导致。解决方法是统一运行时选项。 ### 具体操作步骤: 1. **统一运行时设置**: - 打开项目属性 -> C/C++ -> 代码生成 -> 运行时。 - 确保所有项目(主项目和所有静态、动态)都使用相同的设置(例如,全部为/MD或全部为/MT)。 2. **添加必要的**: - 在链接器 -> 输入 -> 附加依赖项中添加: - `user32.lib`(解决GetAsyncKeyState、GetForegroundWindow) - 如果使用多线程,可能需要`kernel32.lib`等,但通常`user32.lib`已经足够。 3. **检查RTTI设置**: - 确保所有项目都启用RTTI(启用运行时类型信息:是(/GR))。 4. **重新生成解决方案**: - 清理解决方案重新生成。 如果问题仍然存在,可能需要检查: - 是否缺少其他(如`gdi32.lib`、`advapi32.lib`等,根据实际使用的API添加)。 - 符号是否在第三方中定义,而该未正确链接。 ### 示例:设置统一运行时 1. 在Visual Studio中,右键点击项目 -> 属性。 2. 选择“所有配置”和“所有平台”。 3. 进入“C/C++” -> “代码生成”。 4. 将“运行时”设置为相同的选项(例如,多线程调试(/MTd)或多线程(/MT)或相应的动态版本)。 通过以上步骤,应能解决大部分链接错误。 §§相关问题§§ 1. 如何解决Visual Studio中因运行时设置不一致导致的链接错误? 2. 在Windows编程中,常见的API函数需要链接哪些? 3. 如何正确配置Visual Studio项目以使用静态链接运行时?</think>### 解决 LNK2001 链接错误的全面指南 出现多个 `LNK2001: unresolved external symbol` 错误通常由以下原因导致: 1. **文件未链接**:Windows API 或 CRT 函数缺少对应的导入 2. **运行时冲突**:`/MT`(静态链接)和 `/MD`(动态链接)混合使用 3. **符号定义缺失**:编译器内部函数未正确定义 4. **C++ 运行时配置错误**:RTTI 或异常处理未启用 以下是针对您列出的符号的解决方案: --- ### 一、Windows API 函数缺失 #### 1. **GetAsyncKeyState 和 GetForegroundWindow** ```cpp // 函数声明(来自 WinUser.h) SHORT WINAPI GetAsyncKeyState(int vKey); HWND WINAPI GetForegroundWindow(); ``` **解决方法**: 在链接器输入中添加 `user32.lib` - **操作步骤**: 1. 项目属性 → 链接器 → 输入 → 附加依赖项 2. 添加 `user32.lib` 3. 确保包含 Windows SDK 头文件:`#include <Windows.h>` --- ### 二、C++ 运行时符号缺失 #### 2. **operator delete 和 std::_Xlength_error** ```cpp // 典型场景:STL 容器操作触发的异常 std::vector<int> v; v.reserve(-1); // 触发 std::_Xlength_error ``` **解决方法**: 1. 启用 C++ 异常处理: - 项目属性 → C/C++ → 代码生成 → 启用 C++ 异常:**是 (/EHsc)** 2. 统一运行时: - 所有项目组件使用相同的 `/MT`(静态)或 `/MD`(动态)选项 3. 添加标准依赖: ```makefile LIBS = msvcrt.lib libcmt.lib libvcruntime.lib ucrt.lib ``` --- ### 三、CRT 内部函数缺失 #### 3. **atexit, _fltused, __chkstk** 这些是编译器内部函数,通常由 CRT 自动提供。 **解决方法**: 1. 检查运行时一致性: - 静态项目 (`/MT`) 需链接:`libcmt.lib + libvcruntime.lib` - 动态项目 (`/MD`) 需链接:`msvcrt.lib + vcruntime.lib + ucrt.lib` 2. 显式链接 CRT 初始化模块: ```cpp #pragma comment(lib, "vcruntime.lib") extern "C" { extern int _fltused = 0; } // 浮点支持标记 ``` --- ### 四、C++ 特性相关符号 #### 4. **type_info, vftable, tls_index** 这些符号与 RTTI(运行时类型识别)和虚函数表相关。 **解决方法**: 1. 启用 RTTI: - 项目属性 → C/C++ → 语言 → 启用 RTTI:**是 (/GR)** 2. 检查类定义: ```cpp // 确保虚函数有实现体 class Base { public: virtual ~Base() {} // 必须有实现 }; ``` 3. 线程局部存储 (tls_index): ```cpp // 使用 __declspec(thread) 时需链接线程安全 #pragma comment(lib, "libcmt.lib") ``` --- ### 五、系统级符号 #### 5. **_fltused (浮点支持)** **解决方法**: ```cpp // 在任意 .cpp 文件中添加定义 extern "C" { int _fltused = 0x9875; // 任意非零值 } ``` --- ### 完整配置检查清单 1. **统一运行时**(关键步骤) - 检查所有静态和主项目的设置: ```properties /MT 项目:链接 libcmt.lib;libvcruntime.lib /MD 项目:链接 msvcrt.lib;vcruntime.lib;ucrt.lib ``` 2. **链接器设置**: ```makefile AdditionalDependencies = user32.lib # Windows API libcmt.lib # 静态CRT vcruntime.lib # VC运行时 ucrt.lib # 通用CRT ``` 3. **编译器选项**: ```properties /EHsc # 启用C++异常 /GR # 启用RTTI /Zc:__cplusplus # 启用标准宏 ``` > **重要提示**:清理解决方案重新生成所有组件,确保配置一致性[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值