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

升级Delphi后BPL加载资源字符串失败,原因何在?

问题描述

我们有一个包含资源文件(.rc)的BPL,其中的字符串通过STRINGTABLE定义,使用LoadStr()加载。项目原基于Delphi 10.1 Berlin,升级至11.1 Alexandria后,LoadStr()调用返回NULL。

测试时在主函数中添加的代码可正常运行:

extern "C" int _libmain(unsigned long reason)
{
  String str = LoadStr(231); // Works
  return 1;
}

但现有导出函数无法工作:
.h

PACKAGE String __fastcall GetValueSetDesc(int ACount);

.cpp

String __fastcall GetValueSetDesc(int ACount)
{
  String ValueDesc = LoadStr(ACount); // Does not work, returns NULL
  return ValueDesc;
}

已尝试重新创建项目并添加文件,寻求问题原因及解决方法。


可能的原因与解决方法

1. 资源上下文未切换到BPL模块

在Delphi 11中,导出的PACKAGE函数可能默认使用主程序的资源句柄,而非BPL自身的资源句柄。_libmain执行时,模块的资源上下文是当前BPL,所以LoadStr能正常找到资源;但导出函数被调用时,资源上下文可能切换回了宿主程序。

解决方法:手动指定BPL的模块句柄加载字符串,替代LoadStr:

#include <Windows.hpp>
#include <SysUtils.hpp>

// 可选:在_libmain中保存当前模块句柄,避免硬编码文件名
HMODULE g_hModule = nullptr;

extern "C" int _libmain(unsigned long reason)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        g_hModule = GetModuleHandle(nullptr); // 获取当前BPL的模块句柄
    }
    String str = LoadStr(231);
    return 1;
}

String __fastcall GetValueSetDesc(int ACount)
{
    if (!g_hModule) return String();

    wchar_t buffer[256];
    int len = LoadStringW(g_hModule, ACount, buffer, sizeof(buffer)/sizeof(wchar_t));
    return len > 0 ? String(buffer) : String();
}

2. 临时切换资源模块上下文

使用VCL的SetResourceModule函数,临时将资源查找上下文切换到当前BPL,执行完后恢复原上下文:

#include <SysUtils.hpp>

String __fastcall GetValueSetDesc(int ACount)
{
    HMODULE hBplModule = GetModuleHandle(nullptr);
    HMODULE hOldModule = SetResourceModule(hBplModule);
    
    String ValueDesc = LoadStr(ACount);
    
    SetResourceModule(hOldModule); // 恢复原资源模块上下文
    return ValueDesc;
}

3. 检查资源文件编译状态

确认资源文件在Delphi 11中是否正确编译到BPL:

  • 检查BPL项目的资源文件引用是否有效,确保.rc或.res文件已添加到项目中。
  • 尝试手动编译资源文件:使用brcc32工具将.rc编译为.res,再重新添加到项目并编译BPL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:01:12