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

LoadString返回空字符串、FindResource报1814错误的问题排查

问题核心原因

你遇到的资源找不到错误,本质是对Win32 STRINGTABLE 资源的存储规则不熟悉、资源脚本写法或API调用存在错误导致的,FindResource返回1814并不完全代表资源没编译进去,你之前的FindResource调用写法本身就是错误的。

Win32平台的字符串资源不是按单个ID独立存储的,系统会把每16个连续ID的字符串打包成一个资源块:

  • 资源块的ID计算公式为 (字符串ID / 16) + 1
  • 单个字符串在块内的存储位置由 字符串ID % 16 决定
  • 你直接传MAKEINTRESOURCE(POSITIONS_ID)给FindResource,实际查找的是第10号资源块,对应ID范围是144159的字符串,和你ID=10的字符串所在的1号块(对应ID015)完全不匹配,必然返回资源不存在。

修复步骤

按以下顺序排查,绝大多数同类问题都能解决:

  • 修正资源脚本写法
    检查你的.rc文件,确保STRINGTABLE块写法符合规范,注意几个容易踩的坑:

    • 必须正确包含定义POSITIONS_ID的resource.h头文件,宏定义必须是纯数值,不能带表达式,正确的头文件定义参考:
      // resource.h
      #define POSITIONS_ID 10
      
    • STRINGTABLE块要带默认的DISCARDABLE属性,手动写资源脚本很容易漏这个属性:
      #include "resource.h"
          STRINGTABLE DISCARDABLE
          {
              POSITIONS_ID "100 100 \
          200 350 \
          400 800"
          }
    • 多行字符串的续行反斜杠\必须是行尾最后一个字符,后面不能跟空格、注释等任何内容,否则资源编译器会识别续行失败。
    • 确认.rc文件已经加入项目的资源编译列表,没有被设置为“从生成中排除”。
  • 修正LoadString调用参数
    不要给LoadString第一个参数传NULL,NULL代表从系统模块加载资源,不是你自己的程序模块。必须传入当前模块的实例句柄:

    • EXE程序直接用WinMain入口函数传入的hInstance参数
    • DLL模块用DllMain入口传入的hInstance参数
    • GetModuleHandle(NULL)只能拿到EXE的句柄,如果资源写在DLL里,传这个值一样会找不到资源
      正确的调用示例:
    // hInstance 为当前模块的实例句柄
    wchar_t data[100] = {0}; // Windows原生字符串资源为宽字符,优先用W版本API避免编码问题
    int len = LoadStringW(hInstance, POSITIONS_ID, data, 100);
    if (len > 0) {
        // 读取成功,data里就是存储的字符串内容
    }
    
  • 正确验证资源是否存在
    不要用之前错误的FindResource写法验证,正确查找ID=10字符串所在资源块的代码如下:

    UINT blockId = (POSITIONS_ID / 16) + 1;
    HRSRC hRes = FindResourceW(hInstance, MAKEINTRESOURCEW(blockId), RT_STRING);
    if (!hRes) {
        // 这时候返回1814才是真的资源没编译进二进制
        DWORD err = GetLastError();
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:45:41