在.NET中,语言互操作是如何工作的?

3
在 .Net 框架中,我印象中你可以使用一种语言(比如 C++)编写库,然后在其他应用同一框架版本的 C# 项目中导入并干净利落地使用该库。
然而,当 C++ 中定义了某些对于另一种语言(如 C# 或 VB.net)来说没有意义的方法时,例如一个需要一个不是指针的结构体作为参数的方法,我不明白这是如何工作的。
也许我的例子并不成立,因为我对 CLR 的所有语言了解有限,但我必须假设有些语言能做到另一种不能做到的事情 - 我不明白这些差异是如何处理的。
2个回答

3
可以完全使用.NET语言创建一个方法、类、结构体、类型或其他内容,但是另一种.NET语言无法直接调用它。间接调用它(例如通过反射)始终是可能的。也就是说,如果查看任何编译后的C#项目,您会发现编译代码包含一些具有奇怪名称和字符的代码,通常用于支持泛型。其中之一是(包括括号),即使将其作为公共方法,也无法从C#直接调用。
如果语言设计者决定编译成CLR,他们必须支持公共类型的最小子集。这被称为CLS合规性,涉及一种常见的命名约定, 不允许公共指针或公共不安全的成员或类,不允许只有大小写不同的名称,不允许公共静态字段以及其他一些规则。遵守此规则可以保证任何其他.NET语言都可以调用您的方法。他们知道如何做到这一点,因为这方面的规则已经制定并记录下来了。
你甚至可以创建不符合标准的C#代码。它通常会编译,但不能保证所有符合标准的语言都能调用你的方法。大多数其他语言也是如此,包括C++.NET。这是一个微软设计准则,将你的程序集默认标记为CLSCompliant(无论它是用C++、VB还是Ruby编写的)。

2
.NET框架支持不同种类的语言相互操作。Abel所说的是一种,.NET编译器必须生成程序集,其格式在CLI规范中有描述。该规范标准化为Ecma-335,对元数据(类型描述)和代码(IL或Intermediate Language)有严格的描述。这使得相互操作很容易实现,一个语言编译器可以读取另一个语言的类型,而.NET运行时可以让它们协同工作。
但是你说的是C++,那不是一种托管语言。这需要与本地代码进行交互。从技术上讲并不难,毕竟jit也会生成本地代码。你只需要一种方式来描述本地代码,这样就有了成功的可能性。有三种不同的方法:
1. 你可以使用[DllImport]属性声明用本地代码编写的函数,这适用于暴露C风格调用接口的语言运行时。Windows API就是这样。这并不包括C++,至少当你利用它对类的支持时不包括。
2. CLR对COM有很好的支持,它是.NET的祖先,并由Microsoft实现的早期语言相互操作标准。特别是COM Automation子集工作良好,你只需要添加对COM组件类型库的引用,.NET工具会自动生成粘合剂,将组件实现的COM对象模型公开为托管类型。Office interop就是这样工作的,以及在“添加引用”对话框的COM选项卡中找到的所有内容。虽然COM并不要求COM组件必须使用C++编写,但它可能适用于用C++编写的代码。VB6和Delphi是支持COM很好的著名语言。反之亦然,你可以轻松地将.NET代码公开为COM,以供其他运行时使用。WinRT API,允许你编写在Windows 8上运行的Metro应用程序,其核心是基于COM的,尽管在语言投影中它被很好地隐藏了起来。
3. 最终相互操作工具,也是使C++代码可用的工具是C++/CLI语言。它是内置于Microsoft C++编译器中的扩展,允许将本地C++代码编译为IL并存储在程序集中。它还提供了一个选项,以C++样式的语法声明托管类,这些类可直接被托管代码使用,并可以创建本地C++类对象并调用其方法。.NET框架的几个部分都是以这种方式构建的,特别是mscorlib、System.Data和PresentationManager,这些代码块对本地代码有很强的依赖,以完成它们的工作。将C++/CLI视为终极粘合语言。

一如既往的明确答案 ;). 然而,我认为 OP 的意思是他想要使用 Managed C++,就像你提到的第三个选项,因为他写道“假设它们都针对相同的框架版本”。因此,我关注 CLI。 - Abel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接