[英]Delphi XE2: Invoke WinAPI EnumResourceNames cause access violation in Win64 platform
在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;
在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;
第一次檢查時,我希望編譯器會在您的代碼中發出錯誤:
E2094分配給過程變量的本地過程/功能“回調”
但是它沒有這樣做。 我深入研究,發現EnumResourceNames
的回調參數被聲明為Pointer
類型。 如果標頭轉換已將其聲明為類型的回調參數,則確實會發出上述錯誤消息。 在我看來,標題翻譯在這方面很差。 放棄類型系統的安全性似乎沒有什么收獲。
您的代碼可以在32位代碼中工作的事實只是一個偶然的巧合,它取決於實現細節。 您的運氣用完了64位。 同樣,如果啟用了類型檢查系統,則編譯器可能會立即告訴您出了什么問題。
其他一些評論:
EnumRCDataProc
有兩個錯誤的類型: hModule
的類型應為HMODULE
,函數的結果應為BOOL
。 LoadPackage
是獲取模塊句柄的一種相當重量級的方法。 我希望看到帶有LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
和LOAD_LIBRARY_AS_IMAGE_RESOURCE
選項的LoadLibraryEx
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.