C++/CLI
C++/CLI is a variant of the C++ programming language, modified for Common Language Infrastructure. It has been part of Visual Studio 2005 and later, and provides interoperability with other .NET languages such as C#. Microsoft created C++/CLI to supersede Managed Extensions for C++. In December 2005, Ecma International published C++/CLI specifications as the ECMA-372 standard.[1] Syntax changesC++/CLI should be thought of as a language of its own (with a new set of keywords, for example), instead of the C++ superset-oriented Managed C++ (MC++) (whose non-standard keywords were styled like Many conflicting syntaxes, such as the multiple versions of operator C++/CLI uses HandlesIn MC++, there were two different types of pointers: Tracking referencesA tracking reference in C++/CLI is a handle of a passed-by-reference variable. It is similar in concept to using The following code shows an example of the use of tracking references. Replacing the tracking reference with a regular handle variable would leave the resulting string array with 10 uninitialized string handles, as only copies of the string handles in the array would be set, due to them being passed by value rather than by reference. int main() {
array<String^>^ arr = gcnew array<String^>(10);
int i = 0;
for each(String^% s in arr) {
s = i++.ToString();
}
return 0;
}
Finalizers and automatic variablesAnother change in C++/CLI is the introduction of the finalizer syntax In the raw .NET paradigm, the nondeterministic destruction model overrides the protected // C++/CLI
ref class MyClass {
protected:
!MyClass(); // finalizer (non-deterministic destructor) (implemented as Finalize())
public:
MyClass(); // constructor
~MyClass(); // (deterministic) destructor (implemented as IDisposable.Dispose())
static void Test() {
MyClass automatic; // Not a handle, no initialization: compiler calls constructor here
MyClass^ user = gcnew MyClass();
delete user;
// Compiler calls automatic's destructor when automatic goes out of scope
}
};
Operator overloadingOperator overloading works analogously to standard C++. Every For example, comparing two distinct String references ( //effects of reference operator overloading
String^ s1 = "abc";
String^ s2 = "ab" + "c";
Object^ o1 = s1;
Object^ o2 = s2;
s1 == s2; // true
o1 == o2; // false
InteroperabilityC++/CLI allows C++ programs to consume C# programs in C# DLLs.[2] Here the #include "stdafx.h"
#using "...MyCS.dll"
using namespace System;
int main(array<String^>^ args) {
double x = MyCS::Class1::add(40.1, 1.9);
return 0;
}
The C# source code content of MyCS.dll. namespace MyCS;
public class Class1 {
public static double add(double a, double b) {
return a + b;
}
}
This example shows how strings are marshalled from C++ strings to strings callable from C# then back to C++ strings. String marshalling copies the string contents to forms usable in the different environments. #include <string>
#include <iostream>
#include <msclr\marshal_cppstd.h>
#include "stdafx.h"
#using "..MyCS.dll"
using namespace System;
int main() {
std::string s = "I am cat";
String^ clrString = msclr::interop::marshal_as<String^>(s); // string usable from C# (System::String)
String^ t = MyCS::Class1::process(clrString); // call C# function
std::string cppString = msclr::interop::marshal_as<std::string>(t); // string usable from C++
std::cout << "Hello, C++/C# Interop!" << std::endl;
std::cout << cppString << std::endl;
return 0;
}
The C# code is not in any way C++-aware. namespace MyCS;
public class Class1 {
public static string process(string a) {
return a.Replace("cat", "dog") + " with a tail";
}
}
C++/C# interoperability allows C++ simplified access to the entire world of .NET features. C++/CXC++/CX targeting WinRT, although it produces entirely unmanaged code, borrows the References
Further reading
External links |