C++学习(四五五)error: LNK2019: 无法解析的外部符号

本文探讨了在库中使用嵌套结构体时遇到的问题,特别是当这些结构体定义了构造函数时,在库外部创建实例所引发的错误。通过具体的代码示例,分析了错误的原因,并给出了可能的解决方案。
部署运行你感兴趣的模型镜像

库中嵌套结构体/类有以下情况报错:

1、嵌套结构体/类定义有构造函数,在库外定义该嵌套结构体/类对象时报错。

2、嵌套结构体/类定义无构造函数,但是定义有其它函数,在库外定义该嵌套结构体/类对象不报错,访问其函数时报错。

应该是class中struct中的函数的不可见的,如果ProgramEntry中也定义一个函数,访问该函数也会提示无法解析的外部符号。将struct换为class也有此问题。

osgEarth/VirutalProgram
class OSGEARTH_EXPORT VirtualProgram : public osg::StateAttribute
{
    public:        
        struct ShaderEntry
        {
            ShaderEntry();
            bool accept(const osg::State& state) const;
            osg::ref_ptr<PolyShader>                 _shader;
            osg::StateAttribute::OverrideValue       _overrideValue;
            osg::ref_ptr<ShaderComp::AcceptCallback> _accept;
            bool operator < (const ShaderEntry& rhs) const;
        };

        struct ProgramEntry
        {
            osg::ref_ptr<osg::Program> _program;
            unsigned                   _frameLastUsed;
        };
}
osgEarth/VirtualProgram.cpp
VirtualProgram::ShaderEntry::ShaderEntry() :
_overrideValue(0)
{
    //nop
}

bool
VirtualProgram::ShaderEntry::accept(const osg::State& state) const
{
    return (!_accept.valid()) || (_accept->operator()(state) == true);
}

bool
VirtualProgram::ShaderEntry::operator < (const VirtualProgram::ShaderEntry& rhs) const
{
    if ( _shader->getShaderSource().compare(rhs._shader->getShaderSource()) < 0 ) return true;
    //if ( _shader->compare(*rhs._shader.get()) < 0 ) return true;
    if ( _overrideValue < rhs._overrideValue ) return true;
    if ( _accept.valid() && !rhs._accept.valid() ) return true;
    return false;
}

osgEarth::VirtualProgram::ProgramEntry aaa;
osgEarth::VirtualProgram::ShaderEntry bbb;
osgEarth::VirtualProgram::ShaderEntry* ccc;

第一、三句不报错,第二句报错:

main.obj:-1: error: LNK2019: 无法解析的外部符号 "public: __thiscall osgEarth::VirtualProgram::ShaderEntry::ShaderEntry(void)" (??0ShaderEntry@VirtualProgram@osgEarth@@QAE@XZ),该符号在函数 _main 中被引用

第二句改为如下即可(这是有问题的,相当于定义了一个函数):

osgEarth::VirtualProgram::ShaderEntry bbb();

做了一个生成动态库的测试,里面定义了一个class,class中定义了一个struct,如下。如果直接访问如下,是会报错的,如果将struct的构造函数去掉则不会报错。猜测是struct的显式构造函数被隐藏了。

TestClassLib::TestStruct eee;
#ifndef TESTCLASSLIB_H
#define TESTCLASSLIB_H

#include "testclasslib_global.h"

class TESTCLASSLIBSHARED_EXPORT TestClassLib
{

public:
    TestClassLib();

public:
    struct TestStruct{
        TestStruct();
        bool accept(int i) const;
        int       _overrideValue;
        int* _accept;
        bool operator < (const TestStruct& rhs) const;
    };
};

#endif // TESTCLASSLIB_H

您可能感兴趣的与本文相关的镜像

Anything-LLM

Anything-LLM

AI应用

AnythingLLM是一个全栈应用程序,可以使用商用或开源的LLM/嵌入器/语义向量数据库模型,帮助用户在本地或云端搭建个性化的聊天机器人系统,且无需复杂设置

<think>好的,我现在需要解决用户提到的QT C++在Windows下出现的LNK2019错误,具体是无法解析OpenProcessToken和GetTokenInformation这两个函数的外部符号。用户提到这些符号属于链接库缺失的问题,所以我的思路应该是找到这些函数所在的库文件,并在项目中正确配置链接器设置。 首先,我得回忆一下Windows API的相关知识。OpenProcessToken和GetTokenInformation这两个函数属于安全相关的API,通常位于Advapi32.lib这个库文件中。用户之前可能没有在项目中链接这个库,导致编译器找不到这些函数的实现,从而引发LNK2019错误。 接下来,我需要验证这个猜测是否正确。查阅相关文档或经验,确认这些函数确实属于Advapi32.dll,对应的导入库是Advapi32.lib。用户之前的问题中,引用[2]提到了在libcurl配置时添加了Advapi32.lib,这说明用户可能已经了解需要链接某些库,但可能在当前项目中遗漏了。 然后,考虑如何指导用户添加这个库。在Qt项目中,可以通过.pro文件添加链接库,或者在Visual Studio的项目属性中配置。用户之前使用的是Qt,可能更倾向于.pro文件的配置方法。因此,需要给出两种方式的示例:在.pro文件中添加LIBS += -lAdvapi32,或者在VS的项目属性中添加附加依赖项Advapi32.lib。 另外,用户的问题中还提到其他可能的配置问题,比如库目录是否正确。需要提醒用户检查库路径是否包含Advapi32.lib所在的目录,尤其是在使用不同版本的Visual Studio时,路径可能会有所变化,例如引用[3]提到的UniversalCRT_LibraryPath_x86,虽然这可能和当前问题无关,但可以作为参考,确保库路径正确。 还需要考虑调试版和发布版的库是否区分。例如,是否应该使用Advapi32.lib还是其他调试版本,但通常这些系统库不区分调试版,所以直接链接Advapi32.lib即可。 此外,用户可能在64位系统上编译,需要确认平台工具集是否匹配,但这个问题可能更多导致LNK2001而不是LNK2019,不过还是值得提醒用户检查项目配置的平台是否正确。 最后,确保提供的解决方案步骤清晰,分点说明,并给出代码示例,如.pro文件的修改和项目属性的设置截图位置,帮助用户一步步操作。同时,提供验证方法,比如重新编译后是否错误消失,或者使用dumpbin工具检查是否链接了正确的库。 总结,解决方案的核心是链接Advapi32.lib,并确保项目配置正确。此外,考虑到用户之前遇到的类似问题,引用其他库的经验,如libcurl时需要添加多个库,这里同样需要明确指导用户添加正确的库,避免遗漏。</think>### Qt C++ Windows 下 LNK2019 错误解决方案 针对 `OpenProcessToken` 和 `GetTokenInformation` 函数引发的 **LNK2019 无法解析外部符号** 问题,其根源是未正确链接 Windows 安全 API 所需的库文件。以下是具体解决方案: --- #### 1. 添加必需的系统库依赖 这两个函数属于 Windows 安全子系统 API,需要链接 **`Advapi32.lib`** 库。 **配置方法**(任选其一): - **Qt 项目文件(.pro)中添加**: ```qmake LIBS += -lAdvapi32 ``` - **Visual Studio 项目属性中配置**: 1. 右键项目 → **属性** → **链接器** → **输入** → **附加依赖项** 2. 添加 `Advapi32.lib` ![附加依赖项配置位置](https://via.placeholder.com/600x200?text=Linker+Input+Configuration) --- #### 2. 检查库文件路径 若仍报错,需确保链接器能正确找到 `Advapi32.lib`。 **验证步骤**: 1. 检查 **项目属性 → 链接器 → 常规 → 附加库目录** 确保包含 Windows SDK 库路径(如 `C:\Program Files (x86)\Windows Kits\10\Lib\10.0.xxxxx.0\um\x64`)[^3]。 2. 确认项目平台工具集与 SDK 版本匹配(如 VS2019 使用 Windows 10 SDK)。 --- #### 3. 代码兼容性验证 确保函数调用符合 Windows API 规范: ```cpp #include <windows.h> #include <QDebug> // 检查函数调用是否包含正确的参数类型 HANDLE hToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { qDebug() << "OpenProcessToken failed: " << GetLastError(); } // 检查结构体定义是否完整 TOKEN_ELEVATION elevation; DWORD dwSize; if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) { qDebug() << "GetTokenInformation failed: " << GetLastError(); } ``` --- #### 4. 其他可能原因 - **调试/发布模式混淆**:确保 `Advapi32.lib` 在两种模式下均被链接。 - **64/32 位平台不匹配**:检查项目目标平台(x86/x64)是否与库文件架构一致。 --- ### 验证方法 重新编译后若错误消失,则修复成功。若仍报错,可通过以下命令检查符号是否被正确链接: ```cmd dumpbin /symbols YourProject.exe | findstr "OpenProcessToken" ``` --- ### 相关问题 1. 如何判断 Windows API 函数需要链接哪些库文件? 2. Qt 项目中如何处理跨平台的库依赖问题? 3. 除了 `Advapi32.lib`,Windows 开发中常用的系统库还有哪些?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值