CLSCompliant
The Common Language Specification (CLS) is a set of rules for writing managed components that can be accessed by any CLI/.NET-based language. Not all languages support the same constructs. For example, most do not have the notion of pointers, nor do they support unsigned integer types. In addition, not all languages are case-sensitive.
We can indicate whether a program element is CLS-compliant by using an attribute; for example:
using namespace System; [CLSCompliant(true)] public ref class Point sealed { // ... };
The attribute CLSCompliant is false by default. It can be attached to any class member. One can declare a whole class to be CLS-compliant, and then declare one or more of its elements to be non-CLS-compliant. CLS-compliance information can be used by tools that process metadata.
Obsolete
As components evolve over time, it is possible that some of the facilities they export can become superseded. In such cases, we can declare them obsolescent, as follows:
using namespace System; public ref class Calendar { // ... public: [Obsolete("GetMonth is an archaic name; use GetMonthName instead")] String^ GetMonth(int number) { return ""; /* fake it for now */ } String^ GetMonthName(int number) { return ""; /* fake it for now */ } };
As we can see in class Calendar, the old function, GetMonth, has been superseded by GetMonthName. The string provided in the Obsolete attribute can be arbitrary.
using namespace System; int main() { Calendar^ c = gcnew Calendar; String^ str = c->GetMonth(4); }
Note that the class itself is not obsolete, so we can create variables of that type without any warning. However, when we call the obsolete function, the compiler produces the following warning:
warning C4947: 'Calendar::GetMonth' : marked as obsolete
Message: 'GetMonth is an archaic name; use GetMonthName instead'
In some language modes (such as C# and Visual Basic .NET, but not C++ or J#), the source text involving calls to obsolete functions is highlighted, and hovering over it results in a ToolTip containing the attribute's text.
Custom Attributes
We can create our own attribute classes, by deriving them from class Attribute. In doing so, we can define the program elements to which a custom attribute can be attached. Of course, compilers and runtime library code will not be looking for our custom attributes; we'd have to have our own tools to locate and process them. Custom attributes are not discussed further here.
Exercises
To reinforce the material we've covered, perform the following activities:
1. Find out all the fields for the StructLayout attribute that can be given values.
1. Find out all the values for CallingConvention. What are all the fields for this attribute that can be given values?
2. Find out more information about the managed type IntPtr.
3. Hypot is written in C. What changes would we need to make if this function were written in unmanaged C++ instead? The issue here is that, by default, C++ external names are mangled. We can solve this in two ways. If we are able to change the C++ source, we could disable the name mangling; however, this approach is not possible if other programs are currently using that DLL. The alternate approach requires the calling program to use the actual mangled name. Hint: use the DUMPBIN utility from the command line to inspect the DLL to find Hypot's mangled name. Then read about the EntryPoint field on the DllImport attribute.
Notes and Resources
- CLI stands for "Common Language Infrastructure", the subset of .NET that was standardized by Ecma Technical Committee TC39/TG3, and adopted by ISO/IEC. .NET is the name of a Microsoft product that is a superset of the CLI standard. Another implementation of the CLI is Mono, from Novell/Ximian, which runs on Windows and Linux. See http://www.mono-project.com/about/index.html.
- Microsoft's Visual C++ .NET is an implementation of C++/CLI. A free copy of the Express Edition of this product can be downloaded from http://www.microsoft.com/visualc.
- A free copy of the C++/CLI Standard can be downloaded from http://www.ecma-international.org/publications/standards/Ecma-372.htm
For more information on C++/CLI see these other articles by Rex Jaeschke:
- Jan 2005: Getting Started
- Feb 2005: Point Revisited
- Mar 2005: Stack-Based Objects
- Apr 2005: Static Constructors
- May 2005: Value Class Types
- Jun 2005: Inheritance
- Jul 2005: Delegates
- Aug 2005: Interfaces and Generic Types
- Sep 2005: Cloning
- Oct 2005: Threading - Part 1 of 2
- Nov 2005: Threading - Part 2 of 2
- Dec 2005: I/O
- Jan 2006: Serialization
- Feb 2006: Sockets
- Destruction and Finalization