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

简单Windows DirectX应用程序点击关闭后未正常终止,调试出现LNK1168错误的问题排查

我来帮你分析一下这个问题,你遇到的两个现象其实是相关的,根源出在代码里的资源管理和消息循环逻辑上:

问题根源分析

1. 进程无法正常终止的原因

  • Direct3D COM资源未释放:你创建了pD3D、pDev、pVB这些COM对象,但在程序退出前完全没有调用Release()方法释放它们。COM对象依赖引用计数管理生命周期,只要有对象的引用计数不为0,进程就不会正常退出,导致后台持续运行并打印update日志。
  • 消息循环逻辑瑕疵:当前的消息循环在处理完所有消息后才检查WM_QUIT信号,即便收到了退出消息,仍可能继续执行一轮游戏逻辑;而且窗口关闭后,Present操作已经失效,但代码没有处理这种失败场景,会导致无效的渲染循环持续运行。

2. LNK1168编译错误的原因

因为前一次的进程没有正常终止,仍然占用了生成的Game_Loop_Windows_1.exe文件,导致链接器无法写入新的可执行文件,所以会抛出无法打开文件的错误。


解决方案

1. 释放Direct3D资源

在退出消息循环后,添加COM资源释放代码,这是COM编程的基本规范:

// 在消息循环结束后、程序退出前释放所有Direct3D资源
if (pVB) pVB->Release();
if (pDev) pDev->Release();
if (pD3D) pD3D->Release();

把这段代码放在OutputDebugString(_T("--> AFTER MSG LOOP END <--\n"));之前,确保所有创建的COM对象都被正确释放。

2. 修正消息循环逻辑

调整消息循环结构,确保收到WM_QUIT后立即退出,同时处理Present失败的场景:

while (TRUE) {
    // 优先处理系统消息
    if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
        // 收到退出消息直接终止循环
        if (Msg.message == WM_QUIT) {
            break;
        }
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    } else {
        // 仅当无系统消息时执行游戏逻辑
        auto current_time = clock::now();
        auto frame_time = current_time - start_time;
        start_time = current_time;
        lag += duration_cast<nanoseconds>(frame_time);

        while (lag >= timestep) {
            lag -= timestep;
            
            // 检查设备是否还可用,避免窗口关闭后无效渲染
            HRESULT hr = pDev->Clear(0, 0, D3DCLEAR_TARGET, 0xff000000, 1, 0);
            if (FAILED(hr)) {
                PostQuitMessage(0);
                break;
            }
            
            pDev->BeginScene();
            pDev->SetFVF(OURVERT_FVF);
            pDev->SetStreamSource(0, pVB, 0, sizeof(OurVertex));
            pDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
            pDev->EndScene();
            
            hr = pDev->Present(0, 0, 0, 0);
            if (FAILED(hr)) {
                // Present失败说明窗口已失效,主动触发退出
                PostQuitMessage(0);
                break;
            }
            
            update(lag.count());
        }
    }
}

这样修改后,程序会更及时响应退出信号,且窗口关闭后会主动终止游戏循环。

3. 临时应急处理

如果下次再遇到进程未终止的情况,可以打开任务管理器,找到Game_Loop_Windows_1.exe进程并强制结束,就能正常重新编译了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:47:47