3

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

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

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

4

2 回答 2

3

完全可以用一种 .NET 语言创建不能被另一种直接调用的方法、类、结构、类型或其他任何东西。间接调用它(例如通过反射)总是可能的。

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

决定为 CLR 编译的语言设计者必须支持公共类型的最小子集。这被称为CLS 合规性,是关于通用命名约定、没有公共指针或公共不安全成员或类、没有仅按大小写不同的名称、没有公共静态字段和更多规则。当他们遵守此规则时,可以保证任何其他 .NET 语言都可以调用您的方法。他们知道如何做到这一点,因为这方面的规则已经很好地制定并记录在案。

您甚至可以创建不兼容的 C# 代码。它(通常)会编译,但不能保证所有兼容的语言都可以调用您的方法。大多数其他语言也是如此,包括 C++.NET。默认情况下将程序集标记为 CLSCompliant 是 Microsoft 设计指南(无论它是用 C++、VB 还是 Ruby 编写的都无关紧要)。

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

于 2012-06-05T21:39:07.440 回答