"Turn" Win32,win64 programming eternity; 64-bit and 32-machine differences that require attention in language programming

Source: Internet
Author: User

Label:

Original URL: http://www.cnblogs.com/kex1n/archive/2010/10/06/1844737.html

The type of data, in particular int, is different in length under the platform of different bits of machine. The C99 standard does not specify the length size of the specific data type, only the level. To make the comparison:

16-bit Platform

Char 1 bytes 8 bits

Short 2 bytes 16 bit

int 2 bytes 16 bits

Long 4 bytes 32 bits

Pointer 2 bytes

32-bit Platform

Char 1 bytes 8 bits

Short 2 bytes 16 bit

int 4 bytes 32 bits

A long 4 bytes

A long long 8 bytes

Pointer 4 bytes

64-bit Platform

Char 1 bytes

Short 2 bytes

int 4 bytes

A long 8 bytes (difference)

A long long 8 bytes

Pointer 8 bytes (difference)

Second, programming considerations

In order to ensure the universality of the platform, the program should try not to use long database type. You can use a fixed-size data type macro definition:

typedef signed CHAR int8_t

typedef short INT int16_t;

typedef int int32_t;

# if __wordsize = = 64
typedef long int int64_t;
# Else
__extension__
typedef long long int int64_t;

#endif

Third, the use of int can also use intptr_t to ensure the universality of the platform, it is compiled on different platforms of different lengths, but are standard platform length, such as 64-bit machine its length is 8 bytes, 32-bit machine its length is 4 bytes, defined as follows:

#if __wordsize = = 64
typedef long int intptr_t;
#else
typedef int intptr_t;
#endif
Use sizeof to calculate the size of the data type as much as possible in programming

The above type definitions have a corresponding unsigned type.

There are also ssize_t and size_t, respectively, sign size_t and unsigned signed size of computer word size. They also represent the length of the computer, which is int on a 32-bit machine and long on a 64-bit machine, which in a sense equates to intptr_t and uintptr_t. They are defined inside the stddef.h. It is important to note that the accept function of the socket is incorrect for use with size_t on some operating systems because accept receives the int* type, and size_t may be of type long int. Later BSD used sock_t to replace it.

Since the launch of Windows 95 in 1995, the vast majority of Windows applications have moved from the Win16 platform to the Win32 platform, and Windows 3.x and its representative 16-bit Windows programming technology have been quickly penetrated into the limbo. Microsoft's software engineers are now designing the 64-bit Windows programming (WIN64) technology for Intel's IA-64 processor architecture, because Windows 98 is the last product in the Windows 9x series. So Win64 will be included in the development of Windows NT 5.0, when the next generation of Intel's 64-bit processor Merced, software developers can start using 64-bit programming technology, NT enterprise computing capacity is bound to be greatly improved.

Since the 4GB address space satisfies most of the current application requirements, the difference between Win64 and Win32 is much smaller than the difference between Win32 and Win16, so Win64 will not replace Win32 as quickly as Win16 replaces Win32. For a long time to come, Win64 will coexist with Win32 and complement each other. Software developers need to choose the development platform according to the characteristics of the application, or at the same time build the Win64 and Win32 versions of the application, because Win64 and Win32 programming are not very different, in the use of high-level language programming only follow certain principles, It takes a very small amount of time and effort to create the appropriate version for different platforms, and most of the time you can simply recompile the source program once.


LLP64 abstract Data Model ·


The C language standard does not specify how many variables, such as Integer, Long Integer, and pointer, are left to the computing platform, so each system and its application must adopt some default abstract data model as the basis for computation, and Win32 uses a model called LLP32, which assumes the integer type, Long integers and pointer variables have a 32-bit word length, and the corresponding defined int, uint, long, ulong, and handle data types are also 32-bit, which is a reasonable rule for 32-bit Windows programming environments. If you change the word length of integer, Long integer, and pointer variables to 64-bit in Win64, you will not only occupy twice times as much storage space as before, but the existing applications and most of the data types used by them need to be changed, which makes portability between the two platforms very difficult. In fact, after the introduction of 64-bit platforms, the application needs to implement 64-bit addressing, and only a few places need to use 64-bit data, and most of the time using 32-bit data is sufficient, so Win64 uses a kind of abstract data model called LLP64, in addition to the pointer variable to 64-bit, Basic data types, such as Integer and long integer variables, remain 32 bits. Since the basic data types are 32-bit invariant, the data stored on disk does not change its structure and size, and shared data (such as memory-mapped files) between remote or local processes does not have to change its structure and size, which greatly reduces the programmer's workload.

In order to achieve the same source code can be run under the Win32, but also can run under the Win64, define the LLP64 model just out of the first step, and then to define some pointers related to the data types, such as the pointer to calculate the type of data required, etc. The compiler determines whether these data types are 32-bit or 64-bit based on the target platform. These new data types are defined with the C language int and long types, so backward compatibility with Win32 and some Windows API functions is maintained, and Microsoft plans to include these new data types in Beta 2 for Windows NT 5.0. and gradually porting all of the Windows API functions to the 64-bit platform, programmers can start using these data types after the launch of NT 5.0 Beta 2 and the corresponding Platform SDK, when the 64-bit platform is officially launched, Most programs you write will only need to recompile the connection once to generate a 64-bit version.


• New data Types ·


There are three categories of new data types: Fixed precision data type (fixed-precision data types), pointer precision data type (pointer-precision data type), and specified precision pointer (specific-precision Pointers).

1. Fixed-precision data types have the same word lengths in Win32 and Win64, and their names contain their word lengths for ease of memory.

int32 and Int64: the number of signed integers with the word length of 32 and 64 bits respectively;

LONG32 and long64: The number of signed long integers with the word length of 32 and 64 bits respectively;

UInt32 and UInt64: The number of unsigned integers with the word length of 32 and 64 bits respectively;

ULONG32 and ulong64: The number of unsigned long integers with a length of 32 and 64 bits, respectively.

2. The pointer precision data type is the same as the length of the pointer to the target platform (as determined by the compiler), which allows the pointer to be safely converted to the pointer precision data type for algebraic and bitwise operations, regardless of the type of the target platform, regardless of programming.

Int-ptr and Uint-ptr: The number of signed and unsigned integers for pointer precision, the word length of Win32 is 32 bits, and the word length of Win64 is 64 bits;

ssize-t and Size-t: A counter for pointer precision that determines the word length of the pointer precision data type, which is a signed counter.

3. Specific precision pointers remain the same word lengths in both Win32 and Win64, so they are only useful in certain special cases.

-ptr64 (64-bit pointer): In Win32, a 32-bit pointer generates a 64-bit pointer through a symbol extension, and the result of the extension may not be meaningful and can no longer be used as a pointer;

-ptr32 (32-bit pointer): In Win64, the 64-bit pointer generates a 32-bit pointer by truncating the high 32 bits, and the result may not be meaningful and can no longer be used as a pointer.

Using these new data types, you can more clearly show where in your program the computations are actually related to pointers, so it's not easy to make mistakes when you do type conversions, and the data types defined by Win32 don't have that advantage, so new data types help us write more robust code. and ready to migrate to 64-bit platforms in the future.


• Auxiliary development Tools ·


Programming under Win64 is a little different from programming under Win32, because the familiar Windows API functions, in addition to the types of parameters that involve pointers, may change, and nothing more changes, and the original knowledge of the programmer is still useful. To help programmers modify existing source code to use the new data type, Microsoft will include some development aids in NT 5.0 Beta 2, including a header file that defines a new data type basetsd.h and a grammar checker. The grammar checker can check for incorrect type conversions, pointer truncation, and other 64-bit related issues in the source program. For example, it would indicate that the following code has a NO. 4311 pointer truncation Warning:

Buff = (Puchar) Srbcontrol;

(ULONG) Buffer + = srbcontrol->headerlength;

To eliminate the warning, you should change the ulong to uint-ptr so that the code can be run on both Win32 and Win64. The goal of the programmer is to eliminate all warnings issued by the grammar checker, especially the NO. 4311 pointer truncation warning.


• Programming Rules ·


In order to successfully achieve the source-level portability of both platforms, programmers should write programs or modify existing programs according to the following rules.

1. You cannot convert the pointer to an int, uint, long, ulong, DWORD, and so on with a fixed word length of 32 bits, and if you need to perform an operation on the pointer, you should convert the pointer to Int-ptr or UINT-PTR, both of which have the correct word length on different platforms. Also, since handle is essentially a pointer (void *), it is also incorrect to convert handle to a long or ulong type.

2. If you determine that you need to truncate the pointer, you should use Ptrtolong () and Ptrtoulong () two functions (defined in basetsd.h) to block out the pointer truncation warning, but the truncated result cannot be used again as a pointer.

3. When an API function's out parameter can return a pointer, the parameter should be handled with caution, and in Win32, the address of a ULONG variable can be cast to the API function, and the returned pointer is stored in the ULONG variable, but in Win64, the returned pointer is 64 bits. If you use a ULONG variable, you break the contents of other variables, and the correct and simple way is to directly define a pointer variable and pass the address of the pointer variable to the API function as an argument.

4. Handle polymorphic parameters with caution. In Win32, a function can accept a polymorphic parameter with a DWORD parameter, that is, the parameter may have different meanings in different situations, such as an integer number or a pointer. In Win64, if a polymorphic parameter may be interpreted as a pointer, the polymorphic parameter must not be set to the DWORD type, but should be set to the Uint-ptr or pvoid type. Some of the API functions of the Win32 itself, such as raiseexception (), need to be modified because they do not conform to the rule.

5. Use the new get/setwindowlongptr and Get/setclasslongptr API functions. If you hold a pointer in the data area of a window or class, you need to call the function above to access the corresponding variable, in order to help programmers correctly handle this in programming, the header file winuser.h the index value Gwl-wndproc, Gwl-hinstance, The definition of gwl-hwdparent and Gwl_userdata is canceled, and the new index values Gwlp-wndproc, Gwlp-hinstance, Gwlp-hwdparent, and gwlp-userdata are defined instead. The following code will cause a compilation error:

SetWindowLong (Hwnd,gwl-wndproc, (long) mywndproc);

Because Gw-wndproc is not defined, the correct code should be:

Setwindowlongptr (Hwnd,gwlp-wndproc, (int-ptr) mywndproc);

6. Many windows and classes have pointers in their data structures, so you cannot specify offsets in your code to access data members, but you should use Field-offset macros to calculate offsets.

7. Since lparam, wparam, and lresult are usually used to hold pointers or integers, they are all expanded to 64 bits in Win64, so they cannot be mixed with types such as DWORD, ULONG, UINT, int, int, and long. Otherwise, they may be inadvertently truncated.

Other issues to be aware of in the Win64 environment, as well as changes in API functions and new functions under the Win64 platform, are available to interested readers at Microsoft's Web site, or refer to the latest version of the Platform SDK and MSDN Oline Library

"Turn" Win32,win64 programming eternity; 64-bit and 32-machine differences that require attention in language programming

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

Tags Index: