C++/CLI

Last updated
C++/CLI
Paradigm Structured, imperative, object-oriented
Family C
Designed by Microsoft
Developer Microsoft
First appeared2005;18 years ago (2005)
Platform Common Language Infrastructure
Website docs.microsoft.com/en-us/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp
Influenced by
C++, Managed Extensions for C++, C#

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]

Contents

Syntax changes

C++/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 __gc or __value). Because of this, there are some major syntactic changes, especially related to the elimination of ambiguous identifiers and the addition of .NET-specific features.

Many conflicting syntaxes, such as the multiple versions of operator new() in MC++, have been split: in C++/CLI, .NET reference types are created with the new keyword gcnew (i.e. garbage collected new()). Also, C++/CLI has introduced the concept of generics from .NET (similar, for the most common purposes, to standard C++ templates, but quite different in their implementation).

Handles

In MC++, there were two different types of pointers: __nogc pointers were normal C++ pointers, while __gc pointers worked on .NET reference types. In C++/CLI, however, the only type of pointer is the normal C++ pointer, while the .NET reference types are accessed through a "handle", with the new syntax ClassName^ (instead of ClassName*). This new construct is especially helpful when managed and standard C++ code is mixed; it clarifies which objects are under .NET automatic garbage collection and which objects the programmer must remember to explicitly destroy.

Tracking references

A tracking reference in C++/CLI is a handle of a passed-by-reference variable. It is similar in concept to using *& (reference to a pointer) in standard C++, and (in function declarations) corresponds to the ref keyword applied to types in C#, or ByRef in Visual Basic .NET. C++/CLI uses a ^% syntax to indicate a tracking reference to a handle.

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.

intmain(){array<String^>^arr=gcnewarray<String^>(10);inti=0;foreach(String^%sinarr){s=i++.ToString();}return0;}

Note that this would be illegal in C#, which does not allow foreach loops to pass values by reference. Hence, a workaround would be required.

Finalizers and automatic variables

Another change in C++/CLI is the introduction of the finalizer syntax !ClassName(), a special type of nondeterministic destructor that is run as a part of the garbage collection routine. The C++ destructor syntax ~ClassName() also exists for managed objects, and better reflects the "traditional" C++ semantics of deterministic destruction (that is, destructors that can be called by user code with delete).

In the raw .NET paradigm, the nondeterministic destruction model overrides the protected Finalize method of the root Object class, while the deterministic model is implemented through the IDisposable interface method Dispose (which the C++/CLI compiler turns the destructor into). Objects from C# or VB.NET code that override the Dispose method can be disposed of manually in C++/CLI with delete just as .NET classes in C++/CLI can.

// C++/CLIrefclassMyClass{public:MyClass();// constructor~MyClass();// (deterministic) destructor (implemented as IDisposable.Dispose())protected:!MyClass();// finalizer (non-deterministic destructor) (implemented as Finalize())public:staticvoidTest(){MyClassautomatic;// Not a handle, no initialization: compiler calls constructor hereMyClass^user=gcnewMyClass();deleteuser;// Compiler calls automatic's destructor when automatic goes out of scope}};

Operator overloading

Operator overloading works analogously to standard C++. Every * becomes a ^, every & becomes an %, but the rest of the syntax is unchanged, except for an important addition: for .NET classes, operator overloading is possible not only for classes themselves, but also for references to those classes. This feature is necessary to give a ref class the semantics for operator overloading expected from .NET ref classes. (In reverse, this also means that for .NET framework ref classes, reference operator overloading often is implicitly implemented in C++/CLI.)

For example, comparing two distinct String references (String^) via the operator == will give true whenever the two strings are equal. The operator overloading is static, however. Thus, casting to Object^ will remove the overloading semantics.

//effects of reference operator overloadingString^s1="abc";String^s2="ab"+"c";Object^o1=s1;Object^o2=s2;s1==s2;// trueo1==o2;// false

Interoperability

C++/CLI allows C++ programs to consume C# programs in C# DLLs. [2] Here the #using keyword shows the compiler where the DLL is located for its compilation metadata. This simple example requires no data marshalling.

#include"stdafx.h"usingnamespaceSystem;#using "...MyCS.dll"intmain(array<System::String^>^args){doublex=MyCS::Class1::add(40.1,1.9);return0;}

The C# source code content of MyCS.dll.

namespaceMyCS;publicclassClass1{publicstaticdoubleadd(doublea,doubleb){returna+b;}}

This examples 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"usingnamespaceSystem;#using "..MyCS.dll"intmain(){std::strings="I am cat";System::String^clrString=msclr::interop::marshal_as<System::String^>(s);// string usable from C#System::String^t=MyCS::Class1::process(clrString);// call C# functionstd::stringcppString=msclr::interop::marshal_as<std::string>(t);// string usable from C++std::cout<<"Hello, C++/C# Interop!"<<std::endl;std::cout<<cppString<<std::endl;return0;}

The C# code is not in any way C++-aware.

namespaceMyCS;publicclassClass1{publicstaticstringprocess(stringa){returna.Replace("cat","dog")+" with a tail";}}

C++/C# interoperability allows C++ simplified access to the entire world of .NET features.

C++/CX

C++/CX targeting WinRT, although it produces entirely unmanaged code, borrows the ref and ^ syntax for the reference-counted components of WinRT, which are similar to COM "objects". [3]

Related Research Articles

<span class="mw-page-title-main">D (programming language)</span> Multi-paradigm system programming language

D, also known as dlang, is a multi-paradigm system programming language created by Walter Bright at Digital Mars and released in 2001. Andrei Alexandrescu joined the design and development effort in 2007. Though it originated as a re-engineering of C++, D is a profoundly different language — features of D can be considered streamlined and expanded-upon ideas from C++, however D also draws inspiration from other high-level programming languages, notably Java, Python, Ruby, C#, and Eiffel.

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.

In computer programming, run-time type information or run-time type identification (RTTI) is a feature of some programming languages that exposes information about an object's data type at runtime. Run-time type information may be available for all types or only to types that explicitly have it. Run-time type information is a specialization of a more general concept called type introspection.

This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

In computer programming, thread-local storage (TLS) is a memory management method that uses static or global memory local to a thread.

Managed Extensions for C++ or Managed C++ is a now-deprecated set of language extensions for C++, including grammatical and syntactic extensions, keywords and attributes, to bring the C++ syntax and language to the .NET Framework. These extensions were created by Microsoft to allow C++ code to be targeted to the Common Language Runtime (CLR) in the form of managed code, as well as continue to interoperate with native code.

<span class="mw-page-title-main">C Sharp (programming language)</span> Programming language

C# is a general-purpose high-level programming language supporting multiple paradigms. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.

A class in C++ is a user-defined type or data structure declared with keyword class that has data and functions as its members whose access is governed by the three access specifiers private, protected or public. By default access to members of a C++ class is private. The private members are not accessible outside the class; they can be accessed only through methods of the class. The public members form an interface to the class and are accessible outside the class.

Platform Invocation Services, commonly referred to as P/Invoke, is a feature of Common Language Infrastructure implementations, like Microsoft's Common Language Runtime, that enables managed code to call native code.

<span class="mw-page-title-main">Oxygene (programming language)</span> Object Pascal-based programming language

Oxygene is a programming language developed by RemObjects Software for Microsoft's Common Language Infrastructure, the Java Platform and Cocoa. Oxygene is based on Delphi's Object Pascal, but also has influences from C#, Eiffel, Java, F# and other languages.

C# and Visual Basic .NET are the two primary languages used to program on the .NET Framework.

C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.

C++ doesn't have:

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

This comparison of programming languages compares how object-oriented programming languages such as C++, Java, Smalltalk, Object Pascal, Perl, Python, and others manipulate data structures.

In the C++ programming language, placement syntax allows programmers to explicitly specify the memory management of individual objects — i.e. their "placement" in memory. Normally, when an object is created dynamically, an allocation function is invoked in such a way that it will both allocate memory for the object, and initialize the object within the newly allocated memory. The placement syntax allows the programmer to supply additional arguments to the allocation function. A common use is to supply a pointer to a suitable region of storage where the object can be initialized, thus separating memory allocation from object construction.

<span class="mw-page-title-main">.NET Framework</span> Software platform developed by Microsoft

The .NET Framework is a proprietary software framework developed by Microsoft that runs primarily on Microsoft Windows. It was the predominant implementation of the Common Language Infrastructure (CLI) until being superseded by the cross-platform .NET project. It includes a large class library called Framework Class Library (FCL) and provides language interoperability across several programming languages. Programs written for .NET Framework execute in a software environment named the Common Language Runtime (CLR). The CLR is an application virtual machine that provides services such as security, memory management, and exception handling. As such, computer code written using .NET Framework is called "managed code". FCL and CLR together constitute the .NET Framework.

Windows Runtime (WinRT) is a platform-agnostic component and application architecture first introduced in Windows 8 and Windows Server 2012 in 2012. It is implemented in C++ and officially supports development in C++, Rust/WinRT, Python/WinRT, JavaScript-TypeScript, and the managed code languages C# and Visual Basic .NET (VB.NET).

C++/CX(C++ component extensions) is a language projection for Microsoft's Windows Runtime platform. It takes the form of a language extension for C++ compilers, and it enables C++ programmers to write programs that call Windows Runtime (WinRT) APIs. C++/CX is superseded by the C++/WinRT language projection, which is not an extension to the C++ language; rather, it's an entirely standard modern ISO C++17 header-file-based library.

<span class="mw-page-title-main">Standard Libraries (CLI)</span> Standard libraries of C#, the .NET Framework and Core, and related projects

The Standard Libraries is a set of libraries included in the Common Language Infrastructure (CLI) in order to encapsulate many common functions, such as file reading and writing, XML document manipulation, exception handling, application globalization, network communication, threading, and reflection, which makes the programmer's job easier. It is much larger in scope than standard libraries for most other languages, including C++, and is comparable in scope and coverage to the standard libraries of Java.

References

  1. "ECMA-372". ecma-international.org. Ecma International. December 2005. Archived from the original on 10 August 2008.
  2. Using C++ Interop (Implicit PInvoke)
  3. Inside the C++/CX Design - Visual C++ Team Blog - Site Home - MSDN Blogs

Further reading