In a project of mine, I create a DBF file using the TDbf class, which copies values from a source dataset's fields in a loop. When setting the value of the first field, I get an "Access violation" in 64-bit mode and Debug only. I traced it to a line in the TDataSet.DataEvent method, which is overriden in TDbf. What I noticed is that there's a compiler directive around that signature in TDbf:
The new DELPHI_XE matches the signature in Data.DB.pas. However, when called in the TDbf.SetFieldData method, the second parameter is still only passed as a PtrInt:
I think a call to the DataEvent method should be added using the DELPHI_XE compiler directive and a type-cast with NativeInt, which is Int64 is 64-bit:
if not (State in [dsCalcFields, dsFilter, dsNewValue]) then begin
{$ifdef DELPHI_XE}
DataEvent(deFieldChange, Native(Field));
{$else}
DataEvent(deFieldChange, PtrInt(Field));
{$endif}
end;
There are also calls to this method in Dbf.pas that are still only using PtrInfo. I have to admit that I do find it strange that when compiling in Release, it works.
More details: I'm using Delphi XE4 on a Windows 10 machine, with revision 667 of Dbf.
One other thing, I noticed a typo on line 996, the implementation of TDbf.InternalAddRecord, more specifically the SUPPORT_TRECORDBUFFER is missing a 'T' in front of RECORDBUFFER compared to the method declaration in the interface section, line 259.
line 259: procedure InternalAddRecord(Buffer: {$ifdef SUPPORT_TRECORDBUFFER}TDbfRecordBuffer{$else}Pointer{$endif}...
line 996: procedure TDbf.InternalAddRecord(Buffer: {$ifdef SUPPORT_RECORDBUFFER}TDbfRecordBuffer{$else}Pointer{$endif}...
Thanks.
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
nativeint is the type the CPU is most comfortable doing arithmetic with.
PtrInt, and its delphi XE(2)+ eq IntPTR however are the types that have the same type as pointer.
Now usually the size of nativeint and ptrint/intptr will be the same, but logically it isn't. FPC supports all these types since 2013 or so, so there should be only ifdefs for new delphi (and FPC) and old Delphi.
It is possible that some target would keep nativeint smaller than the real size out of some compability with 16/32-bit.
Last edit: Marco van de Voort 2019-08-07
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you Giuseppe, I can compile 64 bit platform on Delphi 12.1 with field update now working fine. I added your ifdef code in dbf.pas.
I have only to fix
DataEvent(deFieldChange, Native(Field));
in
DataEvent(deFieldChange, NativeInt(Field));
Last edit: Giorgio 2024-10-08
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
In a project of mine, I create a DBF file using the TDbf class, which copies values from a source dataset's fields in a loop. When setting the value of the first field, I get an "Access violation" in 64-bit mode and Debug only. I traced it to a line in the TDataSet.DataEvent method, which is overriden in TDbf. What I noticed is that there's a compiler directive around that signature in TDbf:
The new DELPHI_XE matches the signature in Data.DB.pas. However, when called in the TDbf.SetFieldData method, the second parameter is still only passed as a PtrInt:
I think a call to the DataEvent method should be added using the DELPHI_XE compiler directive and a type-cast with NativeInt, which is Int64 is 64-bit:
There are also calls to this method in Dbf.pas that are still only using PtrInfo. I have to admit that I do find it strange that when compiling in Release, it works.
More details: I'm using Delphi XE4 on a Windows 10 machine, with revision 667 of Dbf.
One other thing, I noticed a typo on line 996, the implementation of TDbf.InternalAddRecord, more specifically the SUPPORT_TRECORDBUFFER is missing a 'T' in front of RECORDBUFFER compared to the method declaration in the interface section, line 259.
Thanks.
Now usually the size of nativeint and ptrint/intptr will be the same, but logically it isn't. FPC supports all these types since 2013 or so, so there should be only ifdefs for new delphi (and FPC) and old Delphi.
It is possible that some target would keep nativeint smaller than the real size out of some compability with 16/32-bit.
Last edit: Marco van de Voort 2019-08-07
Thank you Giuseppe, I can compile 64 bit platform on Delphi 12.1 with field update now working fine. I added your ifdef code in dbf.pas.
I have only to fix
in
Last edit: Giorgio 2024-10-08