26 一月 2024
C#到C++ 代码翻译器的设计和开发完全由CodePorting执行。这需要进行许多调查,应用多种方法和测试,涉及内存模型和其他方面的不同。最终,选择了两种解决方案之一,其中一种目前用于Aspose产品的C++版本。
现在是时候解释一下我们在代码翻译器中使用的技术了。该翻译器是一个用C#编写的控制台应用程序,因此可以轻松嵌入到执行典型序列(如翻译-编译-测试)的脚本中。还有一个GUI组件,您可以通过单击按钮来执行相同的操作。
语法分析由NRefactory库在过时的翻译器版本中执行,而在新版本中由Roslyn执行。
该翻译器使用多个AST tree遍历来收集信息并生成输出的C++ 代码。对于C++ 代码,不会创建AST表示,而是以纯文本形式处理输出代码。
在微调翻译器时,有许多情况需要额外的信息。这些信息通过选项和属性传递。选项适用于整个项目。通常,它们用于指定类导出宏名称或在解析代码时使用的C#条件符号。属性适用于类型和实体,并为它们提供一些特定的信息,例如:标记哪些类成员在翻译后的代码中需要const
或mutable
限定符,或者哪些实体应该被排除在翻译之外。
C#类和结构被转换为C++ 类。它们的成员和源代码被转换为最接近的模拟。泛型类型和方法被映射到C++ 模板。C#引用被翻译成智能指针(共享或弱引用)。引用类在Library中定义。代码翻译器的其他内部细节将在单独的文章中描述。
因此,从C#翻译到C++的项目依赖于我们的Library,而不是.NET库:
为了构建代码翻译器库和翻译后的项目,我们使用了Cmake。目前,我们支持VS 2017和2019(Windows)、GCC和Clang(Linux)编译器。
正如已经提到的,我们大部分的.NET实现都是对第三方库的薄适配层,包括:
翻译器和库都经过了许多测试。库的测试使用了GoogleTest框架。翻译器的测试主要使用NUnit/xUnit,并分为几个类别,以确保:
我们使用GitLab作为版本控制系统。在持续集成方面,我们使用Jenkins。翻译后的产品以NuGet包和可下载的存档形式提供。
在开发这个项目时,我们遇到了许多不同的问题。其中一些是预料之中的,而其他一些则是在过程中逐步揭示出来的:
Object
类型的机制,而大多数库类也没有运行时类型信息(RTTI)。这使得将 .NET 类型映射到 STL 类型变得不可能。yield
)。尽管如此,代码翻译器项目从技术角度来看非常有趣,其学术复杂性迫使我们不断学习新知识。
在开发代码翻译器项目时,我们成功地实现了一个解决有趣学术问题的系统,即代码翻译。我们已经按计划发布了 Aspose 库的月度版本,以适用于原本不应该使用的语言。
我们计划发布更多关于代码翻译器的文章。下一篇文章将详细介绍转换过程,包括如何将具体的 C# 构造映射到 C++ 构造。另一篇文章将讨论内存管理模型。
我们将尽力回答提出的问题。如果读者对代码翻译器开发的其他方面感兴趣,我们可以考虑撰写更多相关文章。