error LNK2019: 无法解析的外部符号

在使用UDT进行通信时遇到编译错误LNK2019,该错误提示无法解析外部符号如WSAGetLastError等。通过排查和尝试,发现需要在cpp或h文件中添加#pragma comment(lib,""ws2_32.lib"")来静态链接ws2_32.lib库,从而解决这个问题。ws2_32.lib包含了网络编程所需的API,对于使用这些API的项目是必需的。" 122246472,10148316,RabbitMQ实战指南:从基础到高级特性,"['消息队列', 'RabbitMQ', 'Java开发', '分布式系统', '中间件']

最近在尝试用UDT进行通信,写了两个简单的客户端和服务端,但是编译的时候出现了“error LNK2019: 无法解析的外部符号”错误,为了以后进行总结,还是把解决方法记录下来。

1>------ 已启动生成: 项目: udt_appserver, 配置: Debug Win32 ------
1>生成启动时间为 2013/11/11 20:53:08。
1>InitializeBuildStatus:
1>  正在创建“Debug\udt_appserver.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1>  appserver.cpp
1>ResourceCompile:
1>  所有输出均为最新。
1>ManifestResourceCompile:
1>  所有输出均为最新。
1>api.obj : error LNK2019: 无法解析的外部符号 __imp__WSAGetLastError@0,该符号在函数 "public: int __thiscall CUDTUnited::startup(void)" (?startup@CUDTUnited@@QAEHXZ) 中被引用
1>channel.obj : error LNK2001: 无法解析的外部符号 __imp__WSAGetLastError@0
1>api.obj : error LNK2019: 无法解析的外部符号 __imp__WSAStartup@8,该符号在函数 "public: int __thiscall CUDTUnited::startup(void)" (?startup@CUDTUnited@@QAEHXZ) 中被引用
1>api.obj : error LNK2019: 无法解析的外部符号 __imp__WSACleanup@0,该符号在函数 "public: int __thiscall CUDTUnited::cleanup(void)" (?cleanup@CUDTUnited@@QAEHXZ) 中被引用
1>api.obj : error LNK2019: 无法解析的外部符号 __imp__getsockname@12,该符号在函数 "public: int __thiscall CUDTUnited::bind(int,unsigned int)" (?bind@CUDTUnited@@QAEHHI@Z) 中被引用
1>channel.obj : error LNK2001: 无法解析的外部符号 __imp__getsockname@12
1>api.obj : error LNK2019: 无法解析的外部符号 __imp__ntohs@4,该符号在函数 "private: void __thiscall CUDTUnited::updateMux(class CUDTSocket *,struct sockaddr const *,unsigned int const *)" (?updateMux@CUDTUnited@@AAEXPAVCUDTSocket@@PBUsockaddr@@PBI@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__freeaddrinfo@4,该符号在函数 "public: void __thiscall CChannel::open(struct sockaddr const *)" (?open@CChannel@@QAEXPBUsockaddr@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__getaddrinfo@16,该符号在函数 "public: void __thiscall CChannel::open(struct sockaddr const *)" (?open@CChannel@@QAEXPBUsockaddr@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__bind@12,该符号在函数 "public: void __thiscall CChannel::open(struct sockaddr const *)" (?open@CChannel@@QAEXPBUsockaddr@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__socket@12,该符号在函数 "public: void __thiscall CChannel::open(struct sockaddr const *)" (?open@CChannel@@QAEXPBUsockaddr@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__setsockopt@20,该符号在函数 "private: void __thiscall CChannel::setUDPSockOpt(void)" (?setUDPSockOpt@CChannel@@AAEXXZ) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__closesocket@4,该符号在函数 "public: void __thiscall CChannel::close(void)const " (?close@CChannel@@QBEXXZ) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__getsockopt@20,该符号在函数 "public: int __thiscall CChannel::getSndBufSize(void)" (?getSndBufSize@CChannel@@QAEHXZ) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__getpeername@12,该符号在函数 "public: void __thiscall CChannel::getPeerAddr(struct sockaddr *)const " (?getPeerAddr@CChannel@@QBEXPAUsockaddr@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__ntohl@4,该符号在函数 "public: int __thiscall CChannel::sendto(struct sockaddr const *,class CPacket &)const " (?sendto@CChannel@@QBEHPBUsockaddr@@AAVCPacket@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__WSASendTo@36,该符号在函数 "public: int __thiscall CChannel::sendto(struct sockaddr const *,class CPacket &)const " (?sendto@CChannel@@QBEHPBUsockaddr@@AAVCPacket@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__htonl@4,该符号在函数 "public: int __thiscall CChannel::sendto(struct sockaddr const *,class CPacket &)const " (?sendto@CChannel@@QBEHPBUsockaddr@@AAVCPacket@@@Z) 中被引用
1>channel.obj : error LNK2019: 无法解析的外部符号 __imp__WSARecvFrom@36,该符号在函数 "public: int __thiscall CChannel::recvfrom(struct sockaddr *,class CPacket &)const " (?recvfrom@CChannel@@QBEHPAUsockaddr@@AAVCPacket@@@Z) 中被引用
1>core.obj : error LNK2019: 无法解析的外部符号 __imp__getnameinfo@28,该符号在函数 "private: int __thiscall CUDT::listen(struct sockaddr *,class CPacket &)" (?listen@CUDT@@AAEHPAUsockaddr@@AAVCPacket@@@Z) 中被引用
1>epoll.obj : error LNK2019: 无法解析的外部符号 ___WSAFDIsSet@8,该符号在函数 "public: int __thiscall CEPoll::wait(int,class std::set<int,struct std::less<int>,class std::allocator<int> > *,class std::set<int,struct std::less<int>,class std::allocator<int> > *,__int64,class std::set<unsigned int,struct std::less<unsigned int>,class std::allocator<unsigned int> > *,class std::set<unsigned int,struct std::less<unsigned int>,class std::allocator<unsigned int> > *)" (?wait@CEPoll@@QAEHHPAV?$set@HU?$less@H@std@@V?$allocator@H@2@@std@@0_JPAV?$set@IU?$less@I@std@@V?$allocator@I@2@@3@2@Z) 中被引用
1>epoll.obj : error LNK2019: 无法解析的外部符号 _select@20,该符号在函数 "public: int __thiscall CEPoll::wait(int,class std::set<int,struct std::less<int>,class std::allocator<int> > *,class std::set<int,struct std::less<int>,class std::allocator<int> > *,__int64,class std::set<unsigned int,struct std::less<unsigned int>,class std::allocator<unsigned int> > *,class std::set<unsigned int,struct std::less<unsigned int>,class std::allocator<unsigned int> > *)" (?wait@CEPoll@@QAEHHPAV?$set@HU?$less@H@std@@V?$allocator@H@2@@std@@0_JPAV?$set@IU?$less@I@std@@V?$allocator@I@2@@3@2@Z) 中被引用
1>F:\C_TEST\test_udt\Debug\udt_appserver.exe : fatal error LNK1120: 20 个无法解析的外部命令
1>
1>生成失败。
1>
1>已用时间 00:00:01.05
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========


然后将各个问题进行定位,再手动添加各个.h文件,发现就是治标不治本,最后终于找到解决方法:

#pragma comment(lib,"ws2_32.lib")

也就是在是编写的.cpp或者是.h文件的引用后添加上面那行就行了。
这句话的前面意思是静态加入一个lib文件


也就是库文件


ws2_32.lib文件,提供了对以下网络相关API的支持,若使用其中的API,则应该将ws2_32.lib加入工程(否则需要动态载入ws2_32.dll)。


这句话一般出现在网络编程中,需要使用网络API函数的时候,就必须使用这条语句加载ws2_32.lib库或者动态载入ws2_32.dll。

针对#pragma comment的具体使用方式请参考百度百科:#pragma comment

### LNK2019 错误的解决方案 LNK2019 是 Microsoft Visual Studio 中常见的链接器错误,表示链接器在尝试创建最终的可执行文件或库时,无法找到某个函数、变量或对象的定义。以下是导致该错误的常见原因及解决方法: #### 1. **未正确实现声明的函数** 如果在头文件中声明了一个函数,但未在源文件中提供其实现,则会导致此错误。确保所有声明的函数都有对应的实现[^4]。 ```cpp // MyHeader.h #ifndef MYHEADER_H #define MYHEADER_H void myFunction(); // 声明 #endif // MySrc.cpp #include "MyHeader.h" void myFunction() { // 实现 // 函数体 } ``` #### 2. **忘记编译或链接某些源文件** 如果项目中包含多个 `.cpp` 文件,但未将所有必要的源文件添加到项目中,则可能导致链接器找不到某些符号的定义。检查项目设置,确保所有相关 `.cpp` 文件都被正确添加[^3]。 #### 3. **静态变量未初始化** 对于全局或静态变量,如果仅在头文件中声明而未在源文件中定义,则会导致此错误。确保为静态变量提供定义[^1]。 ```cpp // MyHeader.h extern int globalVar; // 声明 // MySrc.cpp int globalVar = 0; // 定义 ``` #### 4. **链接库缺失或配置错误** 如果项目依赖于外部库(如 Qt 或 SQLite),但未正确配置链接器选项或未指定库路径,则会引发此错误。确保在项目属性中正确配置了库路径和依赖项[^5]。 - 在 Visual Studio 中: - 菜单栏选择 `项目 -> 属性 -> 配置属性 -> 链接器 -> 输入` - 在 `附加依赖项` 中添加所需的库文件名。 - 在 `常规 -> 附加库目录` 中添加库路径。 #### 5. **名称修饰问题** C++ 编译器会对函数名进行修饰(name mangling),以支持重载等功能。如果使用 C++ 编写代码但调用了用 C 编写的库,则需要通过 `extern "C"` 关键字禁用名称修饰[^4]。 ```cpp extern "C" { void cFunction(); // 禁用名称修饰 } ``` #### 6. **入口点问题** 在某些情况下,错误信息可能显示为 `error LNK2019: 无法解析外部符号 WinMain`。这通常是因为项目类型被错误地设置为 Windows 应用程序,但代码中未定义 `WinMain` 函数。检查项目属性中的 `子系统` 设置[^2]。 - 如果项目是控制台应用程序: - 将 `子系统` 设置为 `Console (/SUBSYSTEM:CONSOLE)`。 - 如果项目是图形界面应用程序: - 确保定义了 `WinMain` 函数。 ```cpp int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 入口点代码 return 0; } ``` #### 7. **重复定义或冲突** 有时,多个文件中可能存在同名的全局变量或函数定义,导致链接器混淆。检查是否有重复定义,并确保每个符号在项目中唯一[^3]。 --- ### 示例代码 以下是一个简单的示例,展示如何避免 LNK2019 错误: ```cpp // MyHeader.h #ifndef MYHEADER_H #define MYHEADER_H class MyClass { public: MyClass(); void displayMessage(); }; #endif // MySrc.cpp #include "MyHeader.h" #include <iostream> MyClass::MyClass() {} void MyClass::displayMessage() { std::cout << "Hello, World!" << std::endl; } // Main.cpp #include "MyHeader.h" int main() { MyClass obj; obj.displayMessage(); return 0; } ``` 确保将 `MySrc.cpp` 添加到项目中,并正确配置头文件路径。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值