delphi – EnumResourceNames返回Windows错误998(对内存位置的无
(见底部编辑)
使用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有关,因为如果我替换随机 (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; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |