error C2381: “exit” : 重定义;__declspec(noreturn) 不同

在编译OpenGL Red Book示例时遇到错误提示“exit”重定义的问题,解决方法是调整包含文件的顺序,先引入标准C++库再引入GLUT图形库。

    编译OpenGL   Red   Book   的例子时出现错误,

stdlib.h(406)   :   error   C2381:   “exit”:   重定义;__declspec(noreturn)   不同  
  glut.h(146)   :   参见“exit”的声明  

解决方法:#include <GL/glut.h>
                    #include <stdlib.h>

改成:
                    #include <stdlib.h>
                    #include <GL/glut.h>

通过。

OpenGL和C++有不太融合的地方,在include时要让标准C++类库的头文件位于GLUT图形库头文件之前。
  

<think> 我们正在处理一个关于Visual Studio链接错误LNK2019的问题,特别是涉及__declspec(dllimport)的错误。根据引用内容,我们可以总结出以下常见原因和解决方法: 常见原因: 1. 没有正确链接包含该符号定义的库文件(.lib)。 2. 函数或类的声明和定义不匹配(例如参数类型、调用约定等)。 3. 在链接时,编译器无法找到符号的定义(可能因为未包含源文件或库)。 4. 对于DLL,可能没有正确设置链接器输入依赖项。 5. 编译器设置不一致,比如wchar_t类型的处理方式(如引用[4]中提到的Qt库和项目设置不一致)。 解决方法: 1. 确保链接了正确的库文件(.lib): - 在项目属性中,检查“链接器->输入->附加依赖项”是否包含了所需的.lib文件。 - 确保库文件的路径在“链接器->常规->附加库目录”中设置正确。 2. 检查函数/类声明和定义的一致性: - 检查头文件中的声明和实际实现是否完全一致(包括参数类型、返回值类型、调用约定等)。 - 特别注意是否有__declspec(dllimport)和__declspec(dllexport)的正确使用。在DLL导出时,通常使用宏来切换,例如: ```cpp #ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif ``` 然后在声明导出类或函数时使用`MYDLL_API`。 3. 检查编译器选项是否一致: - 如引用[4]中提到,关于wchar_t类型的设置(项目属性->C/C++->语言->将wchar_t视为内置类型)必须与库编译时的设置一致。 - 确保运行时库的设置一致(如MT/MD等)。 4. 检查DLL的导出: - 使用dumpbin工具检查DLL是否确实导出了该符号。命令:`dumpbin /exports yourdll.dll` - 确保导出的符号名称与链接时需要的名称一致(注意C++的名称修饰)。 5. 确保在包含头文件时,如果该库是动态链接库,在项目设置中应该定义正确的宏(例如,使用库的项目不应该定义导出宏,如`MYDLL_EXPORTS`)。 6. 清理并重新生成解决方案,有时中间文件可能导致链接错误。 7. 如果使用第三方库,检查库的版本是否与当前编译环境兼容(如32位/64位、Debug/Release版本)。 根据以上分析,我们可以为用户提供详细的解决步骤。 §§相关问题§§ 1. 如何检查一个DLL文件导出了哪些符号? 2. 在Visual Studio中如何设置项目属性以正确链接库? 3. 如何解决由于编译器选项不一致导致的链接错误? </think> ### 解决 Visual Studio 错误 LNK2019(无法解析的外部符号 "__declspec(dllimport)")的方法 该错误通常发生在动态链接库(DLL)的符号引用未被正确解析时。以下是系统化的解决步骤: --- #### **1. 检查库文件链接配置** - **添加 .lib 文件**:确保项目的**链接器输入**中包含 DLL 对应的导入库文件(.lib): ```plaintext 项目属性 → 链接器 → 输入 → 附加依赖项 → 添加 xxx.lib ``` - **设置库路径**:指定 .lib 文件的搜索路径: ```plaintext 项目属性 → 链接器 → 常规 → 附加库目录 → 添加 .lib 所在目录 ``` #### **2. 验证声明与定义一致性** - **检查函数签名**:确保 DLL 头文件中的声明(`__declspec(dllimport)`)与 DLL 中的实际定义(`__declspec(dllexport)`)**完全一致**(包括参数类型、返回值、命名空间等)。 - **使用宏统一管理**(推荐): ```cpp // 在DLL项目中定义 #ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif // 声明导出函数 MYDLL_API void MyFunction(); ``` #### **3. 编译器选项一致性** - **字符类型设置**:如引用[^4]所述,确保调用方与 DLL 的 `wchar_t` 设置一致: ```plaintext 项目属性 → C/C++ → 语言 → "将 wchar_t 视为内置类型" → 调整为与DLL编译时相同的选项(是/否) ``` - **运行时库匹配**:检查运行时库配置是否一致(MT/MD/MDd/MTd): ```plaintext 项目属性 → C/C++ → 代码生成 → 运行时库 ``` #### **4. 依赖项检查** - **确认 DLL 可用性**: - 将编译的 DLL 文件复制到可执行文件的输出目录(如 `Debug/` 或 `Release/`)。 - 使用工具(如 **Dependency Walker**)验证 DLL 是否导出目标符号。 - **处理嵌套依赖**:若 DLL 依赖其他库,确保所有次级依赖库已正确链接。 #### **5. 清理并重建** 1. 清理中间文件: ```plaintext 生成 → 清理解决方案 ``` 2. 手动删除 `Debug/`、`Release/` 和 `ipch/` 目录。 3. 重新生成整个解决方案: ```plaintext 生成 → 重新生成解决方案 ``` #### **6. 其他可能原因** - **调用约定不匹配**:检查函数是否使用一致的调用约定(如 `__stdcall` vs `__cdecl`)。 - **符号修饰差异**:确保 DLL 和调用方使用相同的编译器(不同版本 MSVC 的符号修饰规则可能不同)。 - **64/32 位冲突**:确认 DLL 与主程序的目标平台一致(x86/x64)。 --- ### 总结流程图 ```mermaid graph TD A[出现LNK2019错误] --> B{检查链接配置} B -->|缺少.lib| C[添加.lib到附加依赖项] B -->|路径错误| D[设置附加库目录] A --> E{声明/定义是否一致?} E -->|否| F[统一声明/定义宏] A --> G{编译器选项是否匹配?} G -->|wchar_t不一致| H[调整wchar_t设置] G -->|运行时库不一致| I[统一MT/MD等选项] A --> J{DLL位置是否正确?} J -->|否| K[复制DLL到输出目录] A --> L[清理并重建解决方案] ```
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值