How to prepare for 64-bit when upgrading to Delphi 2010 and Unicode

The 64-bit version is not expected to support the 64-bit version, which can no longer wait for the opportunity to transfer our existing code base to unicode and 64-bit at a time. However, it would be nice if we had already prepared our code for 64-bit when translating to Unicode. This will minimize the impact if it finally appears in version 2020. Any suggestions on how to approach this without making a lot of noise if it does not appear before 2020?

+13
64bit migration delphi
Oct 14 '09 at 20:10
source share
4 answers

There is another similar question , but I will also repeat my answer here to make sure that many people see this information:

First of all, disclaimer: although I work for Embarcadero. I can not speak for my employer. What I'm going to write is based on my own opinion about how a hypothetical 64-bit Delphi should work, but there may or may not be competing opinions and other contemplated or unanticipated incompatibilities and events that trigger alternative design decisions.

That said:

  • There are two integer types: NativeInt and NativeUInt, the size of which will float between 32-bit and 64-bit depending on the platform. They have been around quite a few issues. No other integer types will resize depending on the bit size of the target.

  • Make sure that anywhere that relies on a pointer value, an integer or vice versa uses a NativeInt or NativeUInt for an integer type. TComponent.Tag should be NativeInt in later versions of Delphi.

  • I would suggest not using NativeInt or NativeUInt for values โ€‹โ€‹that do not contain pointers . Try to make your code semantically match between 32-bit and 64-bit. If you need 32 bits of a range, use Integer; if you need 64 bits, use Int64. So your code should work the same on both bits. Only if you use a pointer type value of some type, such as a reference or THandle, should you use NativeInt.

  • Pointer-like things should follow similar rules to pointers: an object (obviously), but also things like HWND, THandle, etc.

  • Do not rely on the internal details of strings and dynamic arrays, such as their header data.

  • Our general policy for API changes for the 64-bit version should be to keep the same API between 32-bit and 64-bit, if possible, even if it means that the 64-bit API does not necessarily use the machine . For example, a TList will probably handle MaxInt div SizeOf (Pointer) elements to save Count, indexes, etc. like integer. Since the Integer type will not float (i.e., resize depending on the bit size), we do not want to have a ripple effect on the client code: any indexes that are round-tripped through an Integer variable or an for-loop index will be truncated and potentially cause subtle errors.

  • If the APIs are extended to 64-bit, they will most likely be executed using an additional function / method / property to access additional data, and this API will also be supported in the 32-bit version. For example, the standard Length () procedure is likely to return Integer values โ€‹โ€‹for string type arguments or a dynamic array; if someone wants to deal with very large dynamic arrays, maybe the LongLength () procedure, whose 32-bit implementation is the same as Length (). Length () will throw an exception in 64-bit if applied to a dynamic array with more than 232 elements.

  • In this regard, error checking is likely to be improved to narrow down language operations, especially narrowing 64-bit values โ€‹โ€‹to 32-bit locations. This would affect the convenience of assignment of the return value of Length for locations of type Integer, if Length () returned Int64. On the other hand, especially for compiler-magic functions, such as Length (), there may be some advantage of magic, for example, switch the return type based on context. But an advantage cannot be likewise taken in non-magic APIs.

  • Dynamic arrays probably support 64-bit indexing. Please note that Java arrays are limited to 32-bit indexing even on 64-bit platforms.

  • Lines are likely to be limited to 32-bit indexing. We have time coming up with realistic reasons for people wanting 4GB + strings; these are really strings, not just managed data drops, for which dynamic arrays can also serve.

  • Perhaps built-in assembler, but with limitations, for example, unable to mix freely with Delphi code; There are also rules around exceptions and the layout of the stack frame that must be respected on x64.

+20
Oct 29 '10 at 13:55
source share

First, look at the places where you interact with non-delphi libraries and api calls, they may differ. In Win32, libraries with a standard call to stdcall are called _SomeFunction @ 4 (@ 4, indicating the size of the parameters, etc.). On Win64, there is only one calling convention, and the functions in the dll are no longer formalized. If you import functions from DLL files, you may need to configure them.

Keep in mind that in a 64-bit version of EXE you cannot load a 32-bit DLL, so if you depend on third-party DLL files, you must also check the 64-bit version of these files.

Also, look at Integers, if you depend on their maximum value, for example, when you allow them to overflow and wait for the moment when this happens, this will cause a problem if the size of the integer is changed.

In addition, when working with streams and you want to serialize different data, including an integer, this will cause a problem, since the size of the integer has changed, and your stream will not be synchronized.

So, in places where you depend on the size of the integer or pointer, you will need to make adjustments. When serializing sush data, you also need to keep this size issue in mind, as this can lead to data incompatibility between 32 and 64 bit versions.

In addition, the FreePascal compiler with the Lazarus IDE already supports the 64-bit version. This alternate Object Pascal compiler is not 100% compatible with the Borland / Codegear / Embarcadero Pascal dialect, so just recompiling it for 64-bit may not be so easy, but it can help point out problems with 64-bit.

+7
Oct. 14 '09 at 20:25
source share

Converting to 64 bits should not be very painful. Start with the intentional size of the integer where it matters. Do not use "integer" instead of Int32 for integers of 32 bits, and Int64 for integers of 64 bits. In the last bit conversion, the definition of Integer went from Int16 to Int32, so you play it safe by specifying the exact bit depth.

If you have a built-in assembly, create the equivalent of pascal and create some unit tests to ensure that they work the same. Run some temporary tests and make sure the build is still fast enough to save. If so, you will want to make changes to both as needed.

+6
Oct. 14 '09 at 20:26
source share

Use NativeInt for integers that may contain cast pointers.

+2
Oct 14 '09 at 21:31
source share



All Articles