Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
作为一名程序员,在迁移到64位windows时,我需要担心什么?_Windows_32bit 64bit - Fatal编程技术网

作为一名程序员,在迁移到64位windows时,我需要担心什么?

作为一名程序员,在迁移到64位windows时,我需要担心什么?,windows,32bit-64bit,Windows,32bit 64bit,我最近的大部分编程都是在32位Windows上使用C/C++/C#/VB6进行的。最近,我的客户询问我的代码是否将在64位Windows上运行 我想知道在64位Windows上我可能会使用哪些旧功能?我需要思考和担心哪些现实问题 显然,我将在64位操作系统上测试我的代码,但我想知道需要查找哪些常见问题。我更关心现有的二进制文件,但我愿意接受关于重新编译时需要担心什么的评论(如果可能的话) 编辑:下面是一组64位移植错误。如果您有100%的“类型安全托管代码”,迁移.NET代码可能会更容易。 您只

我最近的大部分编程都是在32位Windows上使用C/C++/C#/VB6进行的。最近,我的客户询问我的代码是否将在64位Windows上运行

我想知道在64位Windows上我可能会使用哪些旧功能?我需要思考和担心哪些现实问题

显然,我将在64位操作系统上测试我的代码,但我想知道需要查找哪些常见问题。我更关心现有的二进制文件,但我愿意接受关于重新编译时需要担心什么的评论(如果可能的话)


编辑:下面是一组64位移植错误。

如果您有100%的“类型安全托管代码”,迁移.NET代码可能会更容易。 您只需将其复制到64位平台并在64位CLR下成功运行即可。 在将32位托管代码迁移到64位时检查此项


顺便说一句,hanselman最近谈到了这个话题。

如果你谈论的是32位程序,那么你几乎不必担心,因为Windows 64将以32位模拟方式运行它们。未来Windows版本(如Windows 7)的任何问题都可能是不兼容,而不是64位操作系统的问题

但是,如果您的托管代码是为“任意CPU”目标平台编译的,并且您对非托管代码(例如PInvoke)进行调用,或者依赖于其他程序集,那么有一些事情需要注意。Scott Hanselman关于x86/x64 CLR的文章涵盖了这一点,并对Win32/64上的CLR进行了很好的解释


在开发64位本机程序时,是一个很好的指南。它主要归结为指针和数据类型的大小:)

从C/C++的角度来看

一件显而易见的事情是int的大小将从4字节变为8字节。如果您的任何代码依赖于此,您可能会得到意外的结果。结构和变量对齐可能会发生变化。你也许可以用一个#pragma pack来克服它,但我在对齐和打包方面不是很流利

如果使用任何包含int的联合,则行为可能会更改

如果您使用的是任何位域结构,则基于int的额外32位可能会导致混淆。标志牌不会在你想的地方

如果您对任何十六进制常量进行编码,并期望符号变为负数,则可能会出现问题。例子 0x8000000是作为日志的负数,或32位整数。0x8000000作为64位平台上的整数是正数。要直接设置符号位,必须使用0x8000000000000000(嵌入空间仅用于可读性)

我还希望尺寸能适当增长。如果您根据MAX_INT进行任何分配,它们将大得多


为了避免这些类型的大小异常,我通常使用long而不是int。

32位程序在64位windows上运行良好。当然,只要您没有进行任何设备驱动程序开发

如果第一次将软件编译为64位软件,则需要注意以下事项:

  • 指针为64位宽,而int为32位。不要将指针存储在整数中,代码将中断
  • 64位进程需要64位DLL。如果您依赖第三方DLL,请确保它们也以64位格式提供。如果需要在32位进程和64位进程之间进行通信,则需要在Windows上使用多种不同的IPC方式。直接调用函数是不可能的
  • 64位Windows上的系统目录与32位Windows上的不同。如果您有一些硬编码的路径,您可能需要再次检查它们

32位模拟真的是防弹的吗?我看到注册表的布局有点不同。我只是想知道什么典型的东西不起作用


此外,C:\windows\SYSTEM32目录只能包含64位DLL。如果你有一个32位的DLL,你需要把它放在C:\windows\syswow64\

据我所知,将C/C++代码移植到64位windows的最重要的一件事是在启用
MEM\u TOP\u DOWN
分配(
AllocationPreference
注册表值)
的情况下测试你的应用程序,如中所述:

要强制分配从较高地址分配到较低地址,以便进行测试,请在调用
VirtualAlloc
时指定
MEM\u TOP\u DOWN
,或将以下注册表值设置为0x100000:

HKEY\U LOCAL\U MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

这什么时候重要

  • 如果您有使用MSVC链接器选项构建的现有32位exe(或通过其他方式(如
    editbin.exe
    )在其PE头中设置了
    IMAGE\u FILE\u LARGE\u ADDRESS\u AWARE
    标志),则它们在64位窗口中获得完整的4 GB虚拟地址空间,您必须使用
    AllocationPreference
    注册表值集测试它们
  • 如果现有32位DLL可能由大型地址感知EXE加载,则必须使用
    AllocationPreference
    注册表值集测试它们
  • 如果将C/C++代码重新编译为64位EXE或DLL,则必须使用
    AllocationPreference
    注册表值集对其进行测试
如果您的C/C++应用程序属于这三类中的一类,并且您没有使用
MEM\u TOP\u DOWN
分配进行测试,那么测试不太可能捕获代码中的任何指针截断/签名错误

第二个最重要的事情是,如果您使用MSVC并且正在为64位重新编译C/C++代码,则为您的64位构建使用
/Wp64
编译器选项:

  • 这将导致编译器对截断指针或将较小的整数类型扩展为指针的类型转换发出警告(即使使用了
    重新解释\u cast
    或C样式转换)