为什么.NET项目有“平台目标”选项? [英] Why for a .NET project there is the option “Platform target”?

查看:55
本文介绍了为什么.NET项目有“平台目标”选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的专家



很抱歉,如果问题可能过于简单或愚蠢,但我在.NET技术中或多或少完全是noob。



我问我,为什么有一个选项平台目标{任何CPU,x86,x64}?我想要理解的是,例如.NET程序集编译成MSIL,及时编译器确实在运行时将此MSIL编译为本机代码。所以对我来说,JIT最终负责决定目前可用的平台。





提前谢谢。





同时我发现了一个非常有用的链接:了解.NET实时编译 [ ^ ]

[/ Edit0]

Dear Experts

Sorry if the question is maybe too simple or stupid, but I’m more or less completely noob in .NET technology.

I’m asking me, why there is an option "Platform target" {"Any CPU", "x86", "x64"}? What I thought to understand is, that e.g. a .NET assembly is compiled into "MSIL" and the "just in time compiler" does compile this MSIL at runtime to "native code". So for me JIT is responsible finally to decide what platform is currently available.


Thank you in advance.


Meanwhile I found a very helpfull link: Understanding .NET Just-In-Time Compilation[^]
[/Edit0]

推荐答案

因为您的代码可能仅限于x86或x64,具体取决于您使用的外部组件,例如Oracle ODP.NET库。如果计算机上的Oracle客户端在64位Windows上为32位,则代码无法以64位运行。它必须限于您正在使用的库的体系结构,因为您不能在同一进程中混合使用32位和64位代码。
Because your code may be limited to either x86 or x64 depending on the external components that you use, like the Oracle ODP.NET library. If the Oracle client on the machine is 32-bit on a 64-bit Windows your code cannot run as 64-bit. It must be limited to the architecture of the libraries that you're using because you can NOT mix 32 and 64-bit code in the same process.


哦......这是如此根本,同时,每个.NET开发人员都应该完全理解这个基本问题。



我将从纯粹实用的经验法则开始:在大多数情况下,只应使用任何CPU目标。然后,正确地说,JIT将负责其余的工作。 (对于那些没有正确理解JIT的人,我只想提一下:.NET代码被编译成CIL代码,并且当应用程序已经运行时,CIL代码在每个方法的基础上编译成本机CPU指令,只要有一些方法需要被调用:通用中间语言 - 维基百科,免费的百科全书 [ ^ ],即时编译 - 维基百科,免费的百科全书 [ ^ ]。)



其他具体平台目标应仅在某些特殊情况下使用。我想,我剩下的问题是描述那些特殊情况。工作流程和决策制定非常简单,但解释起来并不容易。



首先,需要了解支持的64位指令集架构彼此不兼容,但64位架构IE-64(Itanium)和x86-64(AMD64)与x86(32位)兼容。在64位版本的Windows上,通过WoW64子系统支持x86进程。请参阅:

安腾 - 维基百科,免费的百科全书 [ ^ ],

x86-64 - 维基百科,免费的百科全书 [ ^ ],

x86 - 维基百科,免费的百科全书 [ ^ ],

WoW64 - 维基百科,免费的百科全书 [ ^ ]。



另一个事实是:某些应用程序加载的所有程序集都应该使用兼容的指令集架构。这意味着某些程序集可以编译为某些具体的体系结构,而某些程序集可以编译为任何CPU,但编译到任何具体体系结构的所有程序集都应编译为完全相同的体系结构。例如,您可以将x86与Any CPU结合使用,但不能将x86与x86-64或x86-64与Itanium结合使用,依此类推。当然,操作系统应该匹配它,或者,架构应该是x86。有趣的是,在构建时可能会混合错误的目标体系结构,但应用程序会崩溃;这是一个真正的崩溃,而不是一个可恢复的例外。



记住这一点,我们可以使用一个选定的目标架构创建一个应用程序,该架构应该与操作系统(不仅仅是系统上使用的物理CPU)。直到现在,我们才开始关键问题:为什么这样做,在实践中?



我只能看到一个理由:与某些人的兼容性本机代码模块。一个非常典型的情况是:您使用一些本机(非托管)模块。通常,这是一些第三方产品,但它可能是您自己的模块,由于一个或另一个原因,您根本无法将其重写为某种.NET语言。非托管模块没有任何CPU目标,因为它们不使用JIT。您可以使用P / Invoke或C ++ / CLI链接这些模块:

平台调用服务 - 维基百科,免费百科全书 [ ^ ],

C ++ / CLI - 维基百科,免费的百科全书 [ ^ ],

标准ECMA-372 [ ^ ],

从托管代码调用本机函数 [ ^ ]。



开发此类应用程序的一种实用方法是:在.NET程序集中,尽可能使用任何CPU。您只能通过一个程序集(应用程序一个)来控制目标体系结构的最终选择。它的架构应该与所有非托管(本机)模块和目标操作系统的架构相匹配。请记住,x86可用于兼容性,Itanium系统与x86的兼容性远低于x86-64,这是最广泛使用的兼容架构。



另见我的过去回答我在哪里解释为什么尽可能避免P / Invoke很重要:如何在C#中发出哔哔声[ ^ ]。



尽管如此,有些情况下您无法选择。这些是使用具体目标架构可以保存项目的情况。



-SA
Oh… this is so fundamental and, at the same time, so basic question each and every .NET developer should perfectly understand.

I'll start from the purely practical rule of thumb: in most cases, only "Any CPU" target should be used. Then, as you correctly put it, JIT will take care of the rest. (For those not properly understanding JIT, I'll just mention: .NET code is compiled into CIL code, and CIL code is compiled into native CPU instructions when the application is already running, on per-method basis, as soon as some method is required to be called: Common Intermediate Language - Wikipedia, the free encyclopedia[^], Just-in-time compilation - Wikipedia, the free encyclopedia[^].)

The other, concrete platform targets should be used only in some special cases. I guess, the remaining problem for me is to describe those special cases. The workflow and the decisions-making is pretty easy, but the explanation cannot be too easy.

First of all, one needs to understand that supported 64-bit instruction-set architectures are not compatible with each other, but the 64-bit architectures IE-64 (Itanium) and x86-64 (AMD64) are compatible with x86 (32-bit). On 64-bit versions of Windows, x86 processes are supported via the WoW64 subsystem. Please see:
Itanium - Wikipedia, the free encyclopedia[^],
x86-64 - Wikipedia, the free encyclopedia[^],
x86 - Wikipedia, the free encyclopedia[^],
WoW64 - Wikipedia, the free encyclopedia[^].

Another fact is: all the assemblies loaded by some application should use compatible instruction-set architectures. It means that some assemblies can be compiled to some concrete architectures, and some — to "Any CPU", but all the assembles compiled to any concrete architecture should be compiled to exactly the same architecture. For example, you can combine x86 with "Any CPU", but never x86 with x86-64 or x86-64 with Itanium, and so on. Naturally, the OS should match it, or, alternatively, the architecture should be x86. Interestingly, it's possible to mix wrong set of target architectures on build, but the application will crash; and this is a real "crash", not a recoverable exception.

Keeping this in mind, we can create an application using just one chosen target architecture which should match the OS (not just physical CPU used on the system). Only now, we are coming to the key issue: why doing so, in practice?

I can see only one reason to do so: compatibility with some native-code module. A very typical situation is: you use some native (unmanaged) module. Usually, this is some 3rd-party product, but it could be your own module which you simply cannot rewrite to some .NET language, by one or another reason. Unmanaged modules don't have "Any CPU" target, because they don't use JIT. You can link such modules using P/Invoke or C++/CLI:
Platform Invocation Services - Wikipedia, the free encyclopedia[^],
C++/CLI - Wikipedia, the free encyclopedia[^],
Standard ECMA-372[^],
Calling Native Functions from Managed Code[^].

One practical way to develop such application is: in .NET assemblies, use "Any CPU" whenever possible. You can control the ultimate choice of the target architecture by only one assembly, the application one. It's architecture should match the architecture of all the unmanaged (native) modules and target OS. Remember that x86 can be used for compatibility, bit Itanium systems are much less compatible to x86 than x86-64, the most widely used compatible architecture.

See also my past answer where I explain why it's important to avoid P/Invoke whenever possible: How to play beeps in C#[^].

Nevertheless, there are cases when you don't have a choice. And those are the cases when using a concrete target architecture can save your project.

—SA


这篇关于为什么.NET项目有“平台目标”选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆