【问题标题】:How does language interop work in .Net?语言互操作如何在 .Net 中工作?
【发布时间】:2012-06-06 08:07:57
【问题描述】:

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

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

也许由于我对所有 CLR 语言的了解有限,我的示例无法成立,但我必须假设有些事情是一种语言可以做到,而另一种语言却不能——我不明白这些是怎么做到的差异得到处理。

【问题讨论】:

    标签: .net clr


    【解决方案1】:

    完全可以用一种 .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写的都没有关系)。

    【讨论】:

      【解决方案2】:

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

      但是您说的是 C++,它不是一种托管语言。这需要与本机代码互操作。这在技术上并不是很困难,毕竟抖动也会生成本机代码。您只需要一种方法来描述本机代码,这样就有合理的成功机会。有三种不同的方式:

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

      • CLR 对 COM、.NET 之父和 Microsoft 实施的早期语言互操作标准有很好的支持。特别是 COM 自动化子集运行良好,您可以简单地添加对 COM 组件的类型库的引用,.NET 工具会自动生成胶水以将组件实现的 COM 对象模型公开为托管类型。 Office interop 的工作方式与您在“添加引用”对话框的 COM 选项卡中找到的所有内容一样。 可能适用于用 C++ 编写的代码,尽管 COM 当然不需要用 C++ 编写 COM 组件。 VB6 和 Delphi 是很好地支持 COM 的著名语言。反过来,您可以轻松地将 .NET 代码作为 COM 公开给其他运行时。 WinRT api 是一种让您编写在 Windows 8 上运行的 Metro 应用程序的 API,它的核心是基于 COM,尽管它很好地隐藏在语言预测中。

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

      【讨论】:

      • 一如既往的明确答案;)。但是,我假设 OP 意味着他想使用托管 C++,就像在您的第三个选项中一样,因为他写了 “假设它们都针对相同的框架版本”。因此我专注于 CLI。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 2014-12-05
      • 2013-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多