(见底部编辑)
使用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 ), 0, 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;
回调是一个独立的函数(不是对象方法或本地函数)。
在我的调查中,我发现了一些令人困惑的线索:
(Windows732位上的Delphi)
编辑1:创建一个新的Delphi并在其中放置以下行:
enumResult := EnumResourceNames( hInstance, RT_ICON, @EnumCallback, 0 );
结果:错误998。将RT_ICON更改为其他东西,如RT_RTCDATA,问题就会消失。
编辑2:如果我不引用回调中的ResName参数,那么问题就不会发生。(如果我只在回调中说“:= 1结果”,就不会出错。)回到德尔福3 (!)得到了同样的精确结果,所以它不是XE特有的。如果我试图用RT_RCDATA代替RT_ICON,就没问题了,可以读ResName。
发布于 2014-04-12 01:03:14
您没有正确解析回调的lpszType
和lpszName
参数。失败的测试涉及传递给回调的资源ID,而不是资源名称。当您试图通过指针访问进程内存的第一个64 an时,它是无效的内存访问。
您需要测试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;
https://stackoverflow.com/questions/23024402
复制相似问题