You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS2022 C++ DirectX模板添加着色器CreateVertexShader报错VSb无效

VS2022 基础C++ DirectX项目添加着色器触发内存访问错误

问题表现

在VS2022自带的C++ DirectX项目模板基础上手动添加着色器加载逻辑后,程序运行中断在CreateVertexShader调用行,调试显示VSb变量值为0xFFFFFFFFFFFFFFFF,触发内存访问错误。

项目默认生成的BasicAppasdMain构造函数原始代码

BasicAppasdMain::BasicAppasdMain(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
    m_deviceResources(deviceResources)
{
    m_deviceResources->RegisterDeviceNotify(this);

    m_sceneRenderer = std::unique_ptr<Sample3DSceneRenderer>(new Sample3DSceneRenderer(m_deviceResources));

    m_fpsTextRenderer = std::unique_ptr<SampleFpsTextRenderer>(new SampleFpsTextRenderer(m_deviceResources));

}

出错的修改后代码

BasicAppasdMain::BasicAppasdMain(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
    m_deviceResources(deviceResources)
{
    // 注册设备丢失/重建通知
    m_deviceResources->RegisterDeviceNotify(this);

    m_sceneRenderer = std::unique_ptr<Sample3DSceneRenderer>(new Sample3DSceneRenderer(m_deviceResources));

    m_fpsTextRenderer = std::unique_ptr<SampleFpsTextRenderer>(new SampleFpsTextRenderer(m_deviceResources));

    ID3D11VertexShader *VS;
    ID3DBlob* VSb;

    D3DReadFileToBlob(L"..//x64//Debug//BasicAppasd//VertexShader1.cso",&VSb);

    ID3D11Device* pDx11Device = deviceResources->GetD3DDevice();

    pDx11Device->CreateVertexShader(VSb->GetBufferPointer(), VSb->GetBufferSize(), NULL, &VS);
}

错误原因

  • 核心问题是D3DReadFileToBlob调用失败,没有成功加载着色器编译后的cso文件,VSb是未初始化的野指针,并非有效的ID3DBlob实例,后续调用VSb->GetBufferPointer()直接访问非法内存触发崩溃。
  • 路径写法错误:VS运行DirectX模板程序时默认工作目录为项目根目录,硬编码的相对路径..//x64//Debug//BasicAppasd//VertexShader1.cso无法定位到cso文件,同时正斜杠作为路径分隔符不需要写双斜杠。
  • 没有对D3D API的返回值做校验,默认所有调用都成功,是DirectX开发的常见低级错误。

修复方案

  • 先配置HLSL文件的编译属性:右键项目中的VertexShader1.hlsl文件打开属性页,将项类型设置为HLSL编译器,着色器类型选择「顶点着色器(/VS)」,着色器模型选择适配项目的版本(一般选vs_5_0即可),输出文件设置为$(OutDir)%(Filename).cso,确保编译项目时cso文件会生成到程序输出目录。
  • 修正文件路径,添加API返回值校验,修复后的代码如下:
BasicAppasdMain::BasicAppasdMain(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
    m_deviceResources(deviceResources)
{
    m_deviceResources->RegisterDeviceNotify(this);

    m_sceneRenderer = std::unique_ptr<Sample3DSceneRenderer>(new Sample3DSceneRenderer(m_deviceResources));
    m_fpsTextRenderer = std::unique_ptr<SampleFpsTextRenderer>(new SampleFpsTextRenderer(m_deviceResources));

    ID3D11VertexShader *VS = nullptr;
    ID3DBlob* VSb = nullptr;

    // 直接从输出目录读取cso,不要硬编码平台和配置路径
    HRESULT hr = D3DReadFileToBlob(L"VertexShader1.cso", &VSb);
    // 校验读取结果,失败直接终止流程,不要继续执行
    if (FAILED(hr))
    {
        throw std::runtime_error("Failed to load vertex shader cso, please check file path and hlsl compile config");
    }

    ID3D11Device* pDx11Device = deviceResources->GetD3DDevice();
    hr = pDx11Device->CreateVertexShader(VSb->GetBufferPointer(), VSb->GetBufferSize(), nullptr, &VS);
    if (FAILED(hr))
    {
        VSb->Release();
        throw std::runtime_error("Failed to create vertex shader");
    }

    // 后续使用完VS和VSb记得调用Release()释放,推荐用Microsoft::WRL::ComPtr管理COM对象自动释放,避免内存泄漏
}

调试提示:如果仍然提示找不到文件,可以在调用D3DReadFileToBlob前调用GetCurrentDirectory打印当前工作目录,对照调整cso文件存放路径即可。

内容的提问来源于stack exchange,提问作者user11689090

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 15:51:37