Running the following code in Delphi XE2 Win32 platform works. However, the same code compile in win64 platform will cause access violation in "EnumRCDataProc" if run in debug mode:
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;
When debug the code in Delphi XE2 IDE on Win64 platform, I found the value of hModule in EnumRCDataProc doesn't match with variable H. I suspect that might be something wrong about the parameters I constructed for the EnumRCDataProc. However, I can't figure out how. Any ideas?
The problem is that you have made EnumRCDataProc
a local procedure. You need to move it outside the method.
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;
On first inspection I expected that the compiler would emit an error with your code:
E2094 Local procedure/function 'Callback' assigned to procedure variable
But it does not do so. I dug a little deeper and discovered that the callback parameter for EnumResourceNames
is declared as type Pointer
. If the header translation had declared this as a typed callback parameter then the above error message would indeed have been emitted. To my mind the header translation is poor in this regard. There seems very little to be gained from abandoning the safety of the type system.
The fact that your code works in 32 bit code is just a happy coincidence that relies on implementation details. Your luck runs out on 64 bit. Again, if the type checking system had been enabled, the compiler could have told you what was wrong immediately.
Some other comments:
EnumRCDataProc
has a couple of incorrect types in its declaration: hModule
should be of type HMODULE
and the function result should be BOOL
.LoadPackage
is a rather heavyweight approach to getting a module handle. I would prefer to see LoadLibraryEx
with the LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
and LOAD_LIBRARY_AS_IMAGE_RESOURCE
options.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With