加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – EnumResourceNames返回Windows错误998(对内存位置的无

发布时间:2020-12-15 09:34:52 所属栏目:大数据 来源:网络整理
导读:(见底部编辑) 使用EnumResourceNames,我试图在我自己的DLL中找到存储为资源的图标.这是整个DLL代码: library focusRes;{$R focusResResource.res} // contains the icons I need to load{$R *.res}beginend. 我可以使用LoadLibrary和LoadLibraryEx(已验证)
(见底部编辑)

使用EnumResourceNames,我试图在我自己的DLL中找到存储为资源的图标.这是整个DLL代码:

library focusRes;

{$R focusResResource.res} // contains the icons I need to load
{$R *.res}

begin
end.

我可以使用LoadLibrary和LoadLibraryEx(已验证)正确加载DLL.但是对EnumResourceNames的调用返回false,而GetLastError返回998(对内存位置的无效访问).调用代码是:

hdll := LoadLibraryEx( PChar( DLLFilename ),LOAD_LIBRARY_AS_DATAFILE );
// OR: hdll := LoadLibrary( PChar( DLLFilename ));
enumResult := EnumResourceNames( hDll,RT_ICON,@EnumResFlags,0 );
// (hDll is the handle returned from LoadLibrary)

和回调函数:

function EnumResFlags( hDll : HMODULE; ResType,ResName : PChar; 
   notUsed : pointer ) : integer; stdcall;
begin
  // NEVER GETS CALLED
  // log( ResName);
  result := 1; // continue enumeration
end;

回调是一个独立的函数(不是对象方法或本地函数).

在我的调查中,我发现了一些令人困惑的线索:

>问题似乎与我的dll有关,因为如果我替换随机
来自第三方应用程序的DLL,问题就消失了.
>问题似乎不在于我的dll,因为我可以打开它
在第三方图标编辑器中,以及存储在dll中的所有图标都是
正确加载.
>当我尝试为特定图标名称创建资源流时,
异常是“未找到资源[名称]”. (但图标编辑器发现它很好)

(Windows 7 32位上的Delphi XE)

编辑1:创建一个新的Delphi项目并在其中添加以下行:

enumResult := EnumResourceNames( hInstance,@EnumCallback,0 );

结果:错误998.将RT_ICON更改为其他内容,如RT_RTCDATA,问题就消失了.

编辑2:如果我没有在回调中引用ResName参数,则不会发生此问题. (如果我在回调中只说“结果:= 1”,则没有错误.)返回Delphi 3(!)并得到相同的确切结果,因此它并不特定于XE.如果我尝试枚举RT_RCDATA而不是RT_ICON,没有问题枯萎,我可以读取ResName.

解决方法

您没有正确解析回调的lpszType和lpszName参数.您的测试失败涉及将资源ID传递给您的回调,而不是资源名称.当您尝试通过指针访问进程内存的第一个64kb时,它是无效的内存访问.

您需要测试ResType / ResName是否为名称或ID,然后相应地对其进行处理,如下所示:

function EnumResFlags( hDll : HMODULE; ResType,ResName : PChar; notUsed : pointer ) : integer; stdcall;
begin
  if IS_INTRESOURCE(ResName) then
    log(IntToStr(Integer(ResName)))
  else
    log(ResName);
  ...
end;

如果您的Delphi版本没有定义IS_INTRESOURCE(),您可以手动定义它:

function IS_INTRESOURCE(lpszType: PChar): BOOL;
begin
  Result := ULONG_PTR(lpszType) shr 16 = 0;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读