在微软的.NET环境中,C#是主要的编程语言。然而,出于各种原因,项目中的某些部分可能会用其他语言编写(例如现有的包、第三方库、性能等因素)。在这篇文章中,将提出一种认为既好又易于管理的方法,用于在托管代码和非托管代码之间进行交互。
.NET环境是微软对Java的回应,它创建了自己的虚拟机——CLR。C#代码的编译生成了适合这个虚拟机的机器码。微软更进一步,使得其他语言(如C++)的代码也编译成相同的机器语言。因此,可以在C#的DLL或可执行文件中调用C++的DLL,反之亦然。每个团队可以使用其首选的编程语言,并且它们在链接中都能很好地协同工作。
托管代码与非托管代码:在.NET环境中运行的代码称为托管代码。像过去那样运行的代码称为非托管代码。"管理"带来了许多优势,例如"垃圾收集",即回收不再使用的已分配内存。"管理"的缺点是性能较低,并且与现有的非托管代码库交互困难。
IJW(It Just Works):微软提供了一个友好的解决方案,据所知,这个解决方案只存在于C++中。它允许从托管代码调用非托管代码,反之亦然。唯一的限制是,在非托管代码中不会使用"托管"数据类型。因此,可以传递基本数据类型,如int、double,以及定义为"非托管"的数据类型。为了使用这个特性,将创建一个新的DLL或可执行文件作为CLR(托管)的C++项目,然后将非托管代码包围在以下代码中:
#pragma unmanaged
#pragma managed
使用案例示例和代码片段:在一个项目中,在C#中定义了一些类,并创建了一个DLL来保存这些类。这些类旨在为实时程序提供配置。决定实时循环和逻辑将用非托管C++代码编写。创建了另一个用C++编写的DLL,它也使用CLR。这样,用C++编写的DLL就可以引用用C#编写的DLL,并使用代表配置的类。程序本身是用C#编写的。因此,程序熟悉C# DLL中的类。它将它们传递给C++ DLL,后者也熟悉这些类。还有一个问题需要解决。需要将"托管"数据类型转换为"非托管"数据类型,以便调用非托管代码。这里的工作要么是微不足道的,要么是艰难的,但将是轻而易举的。另一种选择是在整个非托管和托管代码中使用非托管数据类型。建议显式转换更方便、更自解释,并且在托管代码和非托管代码之间的边界上最后一刻进行。
以下是代码片段:
*.h文件(C++)
public ref class CConfig {
public:
CConfig(int _a, String^ _str, double _d);
void doTheStuff();
int m_a;
String^ m_str;
double m_d;
};