语言互操作如何在.Net中工作?

时间:2012-06-05 20:33:08

标签: .net clr

在.Net框架中,我的印象是你可以用一种语言编写一个库(比如C ++),然后导入该代码并在其他一些C#项目中干净地使用该库(假设它们都以相同的框架为目标)版本)。

但是,当C ++中定义的方法在C#或VB.net等其他语言中没有意义时,我不明白这是如何工作的,例如一个带有结构的方法参数。一个指针。

由于我对所有CLR语言的了解有限,也许我的例子没有成功,但我必须假设有一种语言可以做的事情,而另一种语言无法做到 - 我不知道这些处理差异。

2 个答案:

答案 0 :(得分:3)

完全可以在一种.NET语言中创建方法,类,结构,类型或任何其他无法直接调用的语言。间接调用它(例如通过反射)总是可以的。

即,如果查看任何已编译的C#项目,您将看到编译后的代码包含一些代码中包含奇怪名称和字符的代码,通常用于支持泛型。其中一个名称是<Module>(包括括号),即使它是公共方法,也不能直接从C#调用。

决定为CLR编译的语言设计者必须支持公共类型的最小子集。这被称为CLS Compliance,约为a common naming convention,没有公共指针或公共不安全成员或类,没有唯一不同的名称,没有公共静态字段和some more rules。当他们遵守此规则时,可以保证任何其他.NET语言都可以调用您的方法。他们知道如何做到这一点,因为这个规则已经很好地规划和记录。

您甚至可以创建non-compliant C# code。它(通常)将编译,但不保证所有兼容的语言都可以调用您的方法。大多数其他语言也是如此,包括C ++ .NET。它是Microsoft Design Guideline to mark your assemblies as CLSCompliant by default(无论是用C ++编写的,VB,Ruby都无关紧要。)

答案 1 :(得分:2)

.NET框架支持不同类型的语言互操作。首先是Abel谈到的那种,.NET编译器必须生成在CLI规范中描述其格式的程序集。标准化为Ecma-335,具有对元数据(类型描述)和代码(IL或中间语言)的严格描述。这使得interop易于实现,一种语言编译器可以读取另一种语言的类型,.NET运行时使它们协同工作。

但是你在谈论C ++,那不是托管语言。这需要与本机代码互操作。在所有抖动生成本机代码之后,这在技术上并不困难。您只需要一种描述本机代码的方法,这样就有合理的成功机会。有三种不同的方式:

  • 您可以使用[DllImport]属性声明用本机代码编写的函数。这适用于暴露C风格调用接口的语言运行时。 Windows API就是这样。这包含C ++,至少在你利用它对类的支持时是这样。

  • CLR很好地支持COM,它是.NET的盛大之父,也是微软实施的早期语言互操作标准。特别是COM自动化子集运行良好,您可以简单地添加对COM组件的类型库的引用,并且.NET工具自动生成粘合剂以将组件实现的COM对象模型公开为托管类型。 Office互操作就像这样,以及您在“添加引用”对话框的“COM”选项卡中找到的所有内容。 可以处理用C ++编写的代码,尽管COM当然不需要用C ++编写COM组件。 VB6和Delphi是支持COM的着名语言。反之,您可以轻松地将.NET代码作为COM公开给其他运行时。 WinRT api,允许你编写在Windows 8上运行的Metro应用程序,它的核心是基于COM的,虽然它在语言预测中很好地隐藏。

  • 最终的互操作工具和您需要用来使C ++代码可用的工具是C ++ / CLI语言。它是Microsoft C ++编译器内置的扩展,它允许将本机C ++代码编译为IL并存储在程序集中。可以选择以C ++样式语法声明托管类,这些类可以由托管代码直接使用,并且可以创建本机C ++类对象并调用其方法。 .NET框架的几个部分是以这种方式构建的,特别是mscorlib,System.Data和PresentationManager,这些代码块完全依赖于本机代码来完成工作。将C ++ / CLI视为最终的粘合语言。