在Delphi XE2 Win32平台上运行以下代码.但是,如果在调试模式下运行,在win64平台中编译相同的代码将导致"EnumRCDataProc"中的访问冲突:
procedure TForm2.Button1Click(Sender: TObject);
function EnumRCDataProc(hModule: THandle; lpszType, lpszName: PChar; lParam:
NativeInt): Boolean; stdcall;
begin
TStrings(lParam).Add(lpszName);
Result := True;
end;
var k: NativeInt;
L: TStringList;
H: THandle;
begin
H := LoadPackage('resource.bpl');
L := TStringList.Create;
try
EnumResourceNames(H, RT_RCDATA, @EnumRCDataProc, NativeInt(L));
ShowMessage(L.Text);
finally
L.Free;
UnloadPackage(H);
end;
end;
Run Code Online (Sandbox Code Playgroud)
在Win64平台上调试Delphi XE2 IDE中的代码时,我发现EnumRCDataProc中的hModule值与变量H不匹配.我怀疑我为EnumRCDataProc构造的参数可能有问题.但是,我无法弄清楚如何.有任何想法吗?
问题是你做EnumRCDataProc了一个本地程序.您需要将其移出方法之外.
function EnumRCDataProc(hModule: HMODULE; lpszType, lpszName: PChar; lParam:
NativeInt): BOOL; stdcall;
begin
TStrings(lParam).Add(lpszName);
Result := True;
end;
procedure TForm2.Button1Click(Sender: TObject);
var k: NativeInt;
L: TStringList;
H: HMODULE;
begin
H := LoadPackage('resource.bpl');
L := TStringList.Create;
try
EnumResourceNames(H, RT_RCDATA, @EnumRCDataProc, NativeInt(L));
ShowMessage(L.Text);
finally
L.Free;
UnloadPackage(H);
end;
end;
Run Code Online (Sandbox Code Playgroud)
在第一次检查时,我预计编译器会使用您的代码发出错误:
E2094分配给过程变量的本地过程/功能"回调"
但它没有这样做.我深入挖掘并发现callback参数为EnumResourceNames声明为type Pointer.如果标头转换已将此声明为类型化的回调参数,则确实会发出上述错误消息.在我看来,标题翻译在这方面很差.放弃类型系统的安全性几乎没有什么好处.
您的代码使用32位代码工作的事实只是依赖于实现细节的快乐巧合.你的运气用完了64位.同样,如果启用了类型检查系统,编译器可能会立即告诉您错误.
其他一些评论:
EnumRCDataProc有几个不正确类型的声明:hModule应该是类型HMODULE和功能的结果应该是BOOL.LoadPackage获取模块句柄是一种相当重要的方法.我宁愿看到LoadLibraryEx与LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE和LOAD_LIBRARY_AS_IMAGE_RESOURCE选项.| 归档时间: |
|
| 查看次数: |
1195 次 |
| 最近记录: |