我总是绕过构建64位桌面应用程序的问题,因为我不知不觉地想到这一点并不是一件容易的事情,而且我想我并没有真正做到这一点。了解解决方案"配置管理器"对话框,平台和配置,或者。
无论如何,我只是尝试通过简单地更改所有解决方案项目来转换现有应用程序'平台到x64,它的工作原理。我唯一的问题是其中一个项目引用的C ++ DLL,需要重建为x64。
所以我的问题(最后)是:为什么我只有C ++ DLL的问题,但我的解决方案中的项目引用的许多.Net程序集DLL都没问题?
实际上是什么决定了我的应用程序是否构建为64位?我将所有解决方案的项目更改为" x64",但是如果将它们保留为"任何CPU",它仍然可以工作,我只更改了WPF(启动) )项目到" x64"?
修改
所以最后我似乎只能将所有项目平台设置为"任何CPU"而不是" x64" (TFS服务器无法使用后者运行单元测试)。甚至引用非托管64位DLL的项目也对此感到满意(不确定原因)。
诀窍是取消选中WPF(启动)项目属性中的Prefer 32-bit
选项。构建的应用程序现在作为64位应用程序运行,并且TFS /单元测试运行愉快。
答案 0 :(得分:5)
从正确性的角度来看,32/64仅在您使用本机代码进行互操作,使用低级别不安全功能或分配大量(> 4GB)内存时才有意义。如果不考虑这些因素,您可以使用AnyCpu。 AnyCpu代码将默认为您的主机操作系统位数(尽管可以更改默认值),因此对于大多数人来说,它最终将以64位进程运行。
有时性能原因明确偏爱32位或64位。 32位应用程序通常会更加缓存友好。当以64位进程运行时,计算绑定应用程序应该表现得更好(但并非总是如此)。
答案 1 :(得分:3)
TL; DR :.Net程序集永远不会汇编到机器特定指令中,而是编译成在.Net虚拟机下运行的MSIL,在运行时VM使用JITer生成机器指令,可由CPU执行。
32bit
和64bit
之间的区别"中断"目标文件是:指针大小,内存模型,最重要的是指令集架构(ISA)。让我们分解每个点,看看为什么.Net
程序集基本上不受影响。
在32bit
执行环境中,指针长度为32位,因为您希望int 64位长度为64位。这个事实可能会以两种方式之一破坏你的装配:
由于.Net语言为safe
- 您无法使用指针(通常,除非您处于不安全的环境中)。没有选择使用指针解决了第二点。至于第一点 - 这就是你可以获得类的大小(使用sizeof
)而不是包含类引用的结构大小的原因。
旧的32bit
处理器曾经有一个名为Memory segmentation
的功能,它允许OS
或Supervisor program
声明使用特殊{{1}访问的内存区域调用CPU registers
。在Segment registers
中,此功能主要是禁用的。因此,在内存分段下编译的程序可能在非分段环境中工作时会出现问题。
通常我们不会在这个低级别处理内存,这可能是因为64bit
,如下一点所述。
.Net virtual machine
和32bit
(64bit
和x86
)相似但完全不同AMD64
这意味着汇编为在一个下运行的代码不会在另一个下运行。所以与其他两点不同的是,无论你写的是什么,这个都会破坏你的装配。
那么.Net程序集怎么可能被编译为ISAs
?诀窍在于,当您编译.Net语言时,您从未组装它。这意味着当您按Any CPU
时,您只需将代码编译为未组装的中间对象(称为.Net程序集)(即,不通过汇编程序运行)。
通常当您在compile
中编译代码时,首先通过编译运行它,生成一些C/++
然后将这些指令传递给生成assembly instructions
的{{1}}。 CPU只能执行这些assembler
。
.Net语言是不同的,如上所述,当您编译.Net语言时,通过编译器运行它并停在那里,不涉及汇编程序。这里的编译也会生成一些machine instructions
,但与machine instructions
编译生成的指令不同,这些指令与机器无关,它们是用assembler instructions
语言编写的。没有CPU知道如何执行这些指令,因为就像普通的汇编程序指令一样,它们也必须组装成机器指令。
诀窍是这一切都发生在运行时,当用户打开程序时,他启动程序运行的c/c++
实例,程序永远不会直接针对本机计算机本身运行。当您的程序需要调用方法时,.Net虚拟机中的一个名为MSIL - Microsoft intermediate language
的特殊组件的任务是将此方法从MSIL组装到特定于该机器的机器指令上。安装.Net框架。