win32,win64编程永恒;语言编程需要注意的64位和32机器的区别

Win32学习笔记开篇语 本专栏要去讲解的,是佩措尔德先生的代码,是98年的代码,所以,我使用的,是比VC++ 6.0新一点,但是也没有新多少的 Visual Studio 2010软件。那么,我写作本专栏的时候,我希望,,对书中的一些个难点,我来展开讲解一下,争取,将书中的难点,都给讲好,讲透。实际上呢,我自己去淘宝网里面搜索Win32方面的教材的时候,所能见到的,除了佩措尔德的那个古董第五版教材之外,很难再找到另外一本教材了。如果,你希望自己编写代码的时候,它的运行效率较高,那么,Win32的学习,应该会是比较有意义的。 阅读详情
一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较:

16位平台

char         1个字节8位

short        2个字节16位

int            2个字节16位

long         4个字节32位

指针         2个字节

32位平台

char         1个字节8位

short        2个字节16位

int            4个字节32位

long         4个字节

long long 8个字节

指针         4个字节

64位平台

char         1个字节

short        2个字节

int            4个字节

long         8个字节(区别)

long long 8个字节

指针        8个字节(区别)

二、编程注意事项

为了保证平台的通用性,程序中尽量不要使用long数据库型。可以使用固定大小的数据类型宏定义:

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

三、使用int时也可以使用intptr_t来保证平台的通用性,它在不同的平台上编译时长度不同,但都是标准的平台长度,比如64位机器它的长度就是8字节,32位机器它的长度是4字节,定义如下:

#if __WORDSIZE == 64
typedef long int                intptr_t;
#else
typedef int                        intptr_t;
#endif
编程中要尽量使用sizeof来计算数据类型的大小

以上类型定义都有相应的无符号类型。

另外还有ssize_t和size_t分别是sign size_t和unsigned signed size of computer word size。它们也是表示计算机的字长,在32位机器上是int型,在64位机器上long型,从某种意义上来说它们等同于intptr_t和uintptr_t。它们在stddef.h里面定义。需要注意的是socket的accept函数在有些操作系统上使用size_t是不正确的,因为accept接收的int*类型,而size_t可能是long int 类型。后来BSD使用sock_t来替代它。



  从1995年windows 95推出至今,绝大多数windows应用程序都已经从win16平台转移到win32平台,windows 3.x及其代表的16位windows编程技术被迅速打入了冷宫。现在,microsoft公司的软件工程师们针对intel公司的ia-64处理器构架又开始了64位windows编程(win64)技术的设计,由于windows 98是windows 9x系列中的最后一个产品,所以win64将被包含在正在开发的windows nt 5.0中,当intel的新一代64位处理器merced推出后,软件开发人员就可以开始使用64位编程技术,nt的企业计算能力势必会得到极大的提高。



  因为4gb的地址空间满足了目前绝大多数应用的需求,win64与win32之间的差异远小于win32与win16之间的差异,所以win64不会像win32取代win16那样迅速取代win32。在今后相当长的一段时间内,win64将与win32和平共处,相互补充。软件开发人员需要根据应用的特点选择开发平台,或者同时建立应用程序的win64和win32版本,由于win64与win32编程区别不大,在使用高级语言编程时只要遵循一定的原则,花费极少量的时间与精力就可以为不同平台创建相应的版本,并且在多数时候只要对源程序重新编译连接一次就可以了。


  ·llp64抽象数据模型·


  c语言标准中没有规定整型、长整型和指针等变量各有多少位,而是留给了计算平台来确定,因此每种系统及其应用都必须采用某种默认的抽象数据模型来作为计算的基础,win32采用一种称为llp32的模型,即假定整型、长整型和指针变量的字长都是32位,相应定义的int、uint、long、ulong和handle等数据类型也都是32位,这对于32位windows编程环境来说是合理的规定。如果win64中把整型、长整型和指针变量的字长都改为64位,那么不仅要占有以前两倍的存储空间,而且现有的应用程序及其使用的大多数数据类型都需要作更改,实现两种平台之间的可移植性就变得相当困难了。事实上,在引入64位平台后,应用程序需要实现64位寻址,并只在少数地方需要用到64位数据,而多数时候使用32位数据就足够了,因此,win64采用了一种称为llp64的抽象数据模型,除了把指针变量扩展到了64位外,整型和长整型变量等基本数据类型仍然保持32位。由于基本数据类型都保持32位不变,所以存储在磁盘上的数据不用改变其结构和大小,远程或本地进程之间的共享数据(如内存映射文件)也不用改变其结构和大小,这就大大减轻了程序员的工作量。

  为了实现同一份源代码既能在win32下运行,也能在win64下运行,定义llp64模型只是走出了第一步,接下来还要定义一些与指针相关的数据类型,如对指针进行计算时需要的数据类型等,编译器会根据目标平台来确定这些数据类型是32位还是64位。这些新的数据类型是用c语言的int和long类型定义的,因此保持了对win32及部分windows api函数的向后兼容性,microsoft计划在windows nt 5.0的beta 2版包含这些新数据类型,并逐渐移植所有的windows api函数到64位平台,程序员在nt 5.0 beta 2版及相应的platform sdk推出后就可以开始使用这些数据类型了,当64位平台正式推出后,所编写的程序多数只需重新编译连接一次即可生成64位版本。


  ·新的数据类型·


  新数据类型共有三类:固定精度数据类型(fixed-precision data types)、指针精度数据类型(pointer-precision data type)和指定精度指针(specific-precision pointers)。

  1.固定精度数据类型在win32和win64中有相同的字长,为了便于记忆,它们的名字中包含了其字长。

  ·int32和int64:字长分别为32位和64位的有符号整型数;

  ·long32和long64:字长分别为32位和64位的有符号长整型数;

  ·uint32和uint64:字长分别为32位和64位的无符号整型数;

  ·ulong32和ulong64:字长分别为32位和64位的无符号长整型数。

  2.指针精度数据类型与目标平台的指针的字长相同(由编译器来确定),这样可以把指针安全地转换成指针精度数据类型来进行代数运算和位运算,而不用编程时处处考虑目标平台的类型。

  ·int-ptr和uint-ptr:指针精度的有符号和无符号整型数,win32下字长为32位,win64下字长为64位;

  ·ssize-t和size-t:指针精度的计数器,用于确定指针精度数据类型的字长,前者为有符号计数器。

  3.特定精度指针在win32和win64中都保持相同的字长,因此只在某些特殊情况下才有用。

  ·-ptr64(64位指针):在win32中,32位指针通过符号扩展生成一个64位指针,扩展的结果可能没有任何意义,不能再当做指针来使用;

  ·-ptr32(32位指针):在win64中,64位指针通过截去高32位生成一个32位指针,结果可能没有任何意义,也不能再当做指针来使用。

  使用这些新的数据类型可以更清晰地显示出程序中哪些地方进行的计算实质上与指针相关,这样在进行类型转换时就不容易出错,而win32中原来定义的数据类型就没有这个优点,因此新数据类型有利于我们编写出更健壮的代码,并且为将来移植到64位平台做好了准备。


  ·辅助开发工具·


  在win64下编程与在win32下编程区别很小,因为大家熟悉的windows api函数除了涉及到指针的参数的类型可能改变外,其他没有什么更多的变化,程序员原有的知识仍然有用。为了帮助程序员修改现有的源代码,转而使用新的数据类型,microsoft将在nt 5.0 beta 2版中包含一些开发辅助工具,其中包括一个定义新数据类型的头文件basetsd.h和一个语法检查器。语法检查器可以检查出源程序中不正确的类型转换、指针截断及其他一些与64位相关的问题。例如它会指出下面的代码存在着4311号指针截断警告:

  buff = (puchar)srbcontrol;

  (ulong)buffer += srbcontrol->headerlength;

  为了消除警告,应该把ulong改为uint-ptr,这样才能保证这段代码既能在win32上运行,也能在win64上运行。程序员的目标是消除所有语法检查器发出的警告,尤其是4311号指针截断警告。


  ·编程规则·


  为了顺利实现两种平台的源代码级可移植性,程序员应按照以下规则来编写程序或者修改已有程序。

  1.不能将指针转换成int、uint、long、ulong、dword等字长固定为32位的类型,如果需要对指针做运算,应把指针转换为int-ptr或uint-ptr,这两种类型在不同平台上才有正确的字长。另外,由于handle实质上是一个指针(void *),因此把handle转换成long或ulong等类型也是不正确的。

  2.如果确定需要对指针进行截断,那么应使用ptrtolong()和ptrtoulong()两个函数(在basetsd.h中定义)来进行,它们可以屏蔽掉指针截断警告,不过截断的结果不能够再当指针使用了。

  3.当某个api函数的out参数能返回一个指针时,应小心谨慎处理参数,在win32中,可以把一个ulong变量的地址进行强制转换后传递给api函数,返回的指针就保存在ulong变量中,但在win64中,返回的指针有64位,如果使用ulong变量的话就会破坏其他变量的内容,正确并且简单的方法是直接定义一个指针变量,把指针变量的地址作为参数传递给api函数。

  4.谨慎处理多态参数。在win32中,一个函数可以用一个dword参数来接受多态参数,即该参数在不同情况下可能具有不同的意义,如解释成整型数或指针。在win64中,如果一个多态参数可能被解释成指针,那么决不能把多态参数设为dword类型,而应设为uint-ptr或pvoid类型。win32自身的一部分api函数(如raiseexception())因为不符合该条规则而需要进行修改。

  5.使用新的get/setwindowlongptr和get/setclasslongptr api函数。如果在窗口或类的数据区中存放了指针,就需要调用上面的函数来存取相应的变量,为了帮助程序员在编程中正确处理这一点,头文件winuser.h把索引值gwl-wndproc、gwl-hinstance、gwl-hwdparent和gwl_userdata的定义取消了,转而定义了新的索引值gwlp-wndproc、gwlp-hinstance、gwlp-hwdparent和gwlp-userdata。这样下面的代码将会引起编译错误:

  setwindowlong(hwnd,gwl-wndproc,(long)mywndproc);

  因为gw-wndproc没有定义,正确的代码应为:

  setwindowlongptr(hwnd,gwlp-wndproc,(int-ptr)mywndproc);

  6.许多窗口和类的数据结构中包含了指针,因此不能在代码中强行指定偏移量来访问数据成员,而应使用field-offset宏来计算偏移量。

  7.由于lparam、wparam和lresult通常用来存放指针或整数,在win64中它们全部被扩展成为64位,因此不能把它们与dword、ulong、uint、int、int和long等类型混用,否则可能会无意识地把它们截短了。

  关于在win64环境下编程还需要注意的其他问题,以及win64平台下api函数的变化及新增函数,有兴趣的读者可到microsoft的web站点查阅相关资料,或者参考最新版的platform sdk及msdn oline library。
记录C/C++库从32位机器向64为机器移植过程中导致的问题和解决方案 博客搬家,原地址:https://langzi989.github.io/2018/01/01/C中记录基础库从32位到64位机器移植导致的一些问题/ 最近程序库从32为向64为机器移植后,在使用过程中出现了一些问题,其中包括上一篇中记录的由于va_list类型不一致导致程序core dump或者出现异常行为的原因,这篇文章记录一下库移植之后出现的小问题。持续更新… 问题一: unsigned l... 阅读详情

相关推荐

Visual C++ VC程序开发宝典:Windows平台遗留系统维护与实战指南

在Windows平台软件开发领域,Visual C++(VC)作为经典的开发环境,其核心价值在于对底层系统资源的直接控制和高性能计算能力。其技术原理基于微软的C++编译器与Windows API的深度集成,通过MFC框架和Win32 API提供了构建稳定桌面应用的成熟方案。这一技术栈在工业控制、嵌入式上位机、图形处理及驱动开发等特定领域具有不可替代的工程价值,尤其适用于维护和升级遗留系统。本书聚焦于VC开发中的环境配置、项目迁移、MFC/Win32 API精要及工程化实践等核心议题,旨在帮助开发者系统掌握在

搜索 350

精通Win32 API编程-Windows图形界面编程

Windows的API(Application Programming Interface,应用程序编程接口),是Windows 操作系统提供给应用程序的大量函数,学习本课程,不仅可以掌握Windows界面编程,开发华丽的Windows桌面运用程序,也可以为MFC框架的学习奠定扎实的基础,同时是否熟练的掌握Windows API开发,也是企业考量优秀程序员一个非常重要的指标!

android11-修改屏幕显示方向和触摸方向

参数0表示12点钟方向显示参数90表示3点钟方向显示参数180表示6点钟方向显示参数270表示9点钟方向显示。

Paper_Love的博客 2118

告别即将远去的win32时代

       随着linux的兴起和微软下一代操作系统的普及,我们即将告别win32时代。现代应用系统的一个重要特征是跨平台性。微软的.net框架中,托管代码是其重要特征之一,也就是说在windows写的程序可以脱离windows系统执行,.net框架有点类似于java的虚拟机,多平台化,微软帝国显然已经接受了这样的事实,并一直在为迎接下一代的软件开发模式而努力。      DOS时代的编程我

loverwei的专栏 1807

手把手教你用光耦搭建安全隔离电路:从洗衣机控制板到PLC输入模块实战

本文通过洗衣机控制板驱动高压电机和PLC输入模块采集现场信号两个实战场景,手把手教你使用光耦搭建安全隔离电路。文章详细解析了电路架构、关键器件选型、参数计算、仿真验证及PCB布局避坑技巧,并对比了光耦与数字隔离器的适用场景,帮助电子工程师掌握这门保障系统稳定与安全的必备技能。

h6j7k8l9p0的博客 462

Kettle Web版部署指南

看到以上的日志则表示启动成功。

2401_89221867的博客 1715

【转】win32,win64编程永恒;语言编程需要注意的64位和32机器的区别

原文网址:http://www.cnblogs.com/kex1n/archive/2010/10/06/1844737.html 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较: 16位平台 char 1个字节8位 short 2个字节16位 int...

weixin_30539625的博客 124

三甲医院网络架构与安全建设实战

华为OceanStor] [华为OceanStor][PACS存储双活] [HIS数据库同步]患者隐私 数据脱敏 天清Web防火墙动态脱敏策略。主数据中心 --[OTV专线]-- 备数据中心。实现医疗业务网/卫生专网/互联网三网隔离。核心业务配置(华为CE6865)自动备份配置(每天02:00)安全事件响应(30分钟SLA)漏洞扫描(每周日00:00)实现医疗物联网统一接入管控。五、等保2.0合规关键配置。堡垒机登录(双因素认证)四、医疗物联网安全方案。

有小小的远大抱负 1909

WINDOWS 32位与64位系统的编程差异

win32,win64编程永恒;语言编程需要注意的64位和32机器的区别 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较: 16位平台 char 1个字节8位 short 2个字节16位 int 2个字节16位 long 4个字节32位 指针 ...

weixin_30618985的博客 197

FFmpeg + OBS 低延迟直播串流实战:从H264裸流到RTP组播的完整配置

本文详细介绍了如何利用FFmpeg将H264裸流转码为RTP协议,并通过组播技术实现与OBS客户端的超低延迟直播串流。文章深入剖析了FFmpeg关键参数调优、SDP文件生成与配置,以及OBS客户端的无缝拉流方法,为需要毫秒级实时交互的场景提供了一套去中心化、高效稳定的完整解决方案。

fanta的博客 827

GN算法边介数计算优化指南:如何提升大规模社交网络分析效率

本文深入探讨了GN算法在大规模社交网络分析中的核心瓶颈——边介数计算,并提供了从算法优化到工程部署的完整性能提升方案。通过引入Brandes算法、并行计算、增量更新及分布式处理等策略,有效解决了传统GN算法在处理百万级网络时效率低下的问题,为社交网络社区划分等实际应用提供了高效解决方案。

weixin_29196613的博客 485

win32,win64编程的区别

win32,win64编程永恒;语言编程需要注意的64位和32机器的区别 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较: 16位平台 char      1个字节8位 short        2个字节16位 int         2个字节16位 long      4个字节32位 指针

lionzl的专栏 3778

ESP32与INMP441麦克风模块实现音频传输

ESP32是一款低成本、低功耗的物联网开发板,支持Wi-Fi和蓝牙双模通信,内置双核处理器,适合音频处理和实时数据传输。INMP441是一款高性能数字麦克风模块,支持I2S接口,可提供高精度音频数据采集(24-bit分辨率,64-100 dB SNR)。

走向CTO的路上... 2039

win32,win64编程永恒;语言编程需要注意的64位

win32,win64编程永恒;语言编程需要注意的64位和32机器的区别 作者:拳拳的Blog | 出处:博客园 | 2011/12/10 7:17:51 | 阅读79次 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较: 16位平台 char         1个字节8位 short

linuxheik的专栏 844

VN5620以太网测试——DoIP配置

CANoe(CAN open environment)VN5620 :是一个紧凑而强大的接口,用于以太网网络的分析、仿真、测试和验证。VN5620 接口支持各种可能的应用。它适用于与其他总线系统、网络参与(例如在模拟和生成帧、测试中的负载和错误)的同步以太网监控。在2021年Vector公司的以太网接口卡VN5610和VN5640设备已经陆续停产,相应被VN5620和VN5650代替。参考文章了解DoIP协议——汽车以太网应用介绍。

诊断协议那些事儿's blog 3005

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

WINDOWS_32位与64位系统的编程差异

win32,win64编程永恒;语言编程需要注意的64位和32机器的区别 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较: 16位平台 char      1个字节8位 short        2个字节16位 int         2个字节16位 long      4个字节32位 指针      

痞子龙3D编程 7830

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

32位和64位系统对于程序员的影响

win32,win64编程永恒;语言编程需要注意的64位和32机器的区别 一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较: 16位平台 char      1个字节8位 short        2个字节16位 int         2个字节16位 long      4个字节32位 指针      

吉祥的专栏 4861

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

C编程注意32位机器和64位机器的差别及unsigned和signed

1.64bit CPU拥有更大的寻址能力,最大支持到16GB内存,而32bit只支持4G内存 2.64位CPU一次可提取64位数据,比32位提高了一倍,理论上性能会提升1倍。但这是建立在64bit操作系统,64bit软件的基础上的。C/C++ 32位机器和64位机器 差异问题总结 跨平台 移植问题 语言编程需要注意的64位和32机器的区别#include < stddef.h> OS versi

樊茂林的博客 8461

64位与32位处理器编程的差异和需要注意的问题

目前正在将一个32位平台的上的软件移植到64位的处理器上来。在移植的过程中遇到了如下的几个问题,与大家共享。 1. 指针长度的差异,在32位处理器上指针的长度为4字节,在64位处理器上,指针的长度为8字节。在平台的移植过程中,出现了指针越界的问题,问题的根源在于程序中假设了指针的长度为4字节,没有考虑到代码的跨平台可移植性问题。标准的情况下,应该用sizeof取代常量假设。 sizeo

yu0089的专栏 1377
上一篇: C/C++面试常见的几个库函数详解(strcpy,memcpy,memset,atoi...)
下一篇: 利用命令切换CTabCtrl控件的Tab页面
cbNotes
博客等级 码龄14年 295粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值