IT Computer Training Articles Tutorials - Submit Your Article - Articles Submission Directory. - http://www.articles.webtechvision.com
Special Features of Visual C++ .NET
http://www.articles.webtechvision.com/articles/260/1/Special-Features-of-Visual-C-NET/Page1.html
Lyli mee
 
By Lyli mee
Published on 09/22/2007
 

With such a large change in the way Visual C++ applications are written within Visual Studio .NET, it should come as no surprise that Microsoft has added several language features to accommodate writing applications for the .NET framework while still maintaining the ability to create older Visual C++ application types. Through the addition of new language keywords, attributes, preprocessor directives, and new compiler and linker switches, the ability to create such differing styles of applications makes the task much easier.


Special Features of Visual C++ .NET

With such a large change in the way Visual C++ applications are written within Visual Studio .NET, it should come as no surprise that Microsoft has added several language features to accommodate writing applications for the .NET framework while still maintaining the ability to create older Visual C++ application types. Through the addition of new language keywords, attributes, preprocessor directives, and new compiler and linker switches, the ability to create such differing styles of applications makes the task much easier.

In this tutorial, you will learn about the new special features for writing .NET applications in Visual C++ .NET.

Specifically, in this hour you will learn:

  • New language keywords

  • Attributes and how they are defined

  • Pragmas that specify managed or unmanaged code

  • Preprocessor directives

  • Compiler options

  • Linker options


Using the New Language Keywords

Several new keywords has been added to the Visual C++ .NET compiler so that it can build .NET Framework applications. The reason for some of these additions is to maintain cross-language interoperability (CLI), a standard that Microsoft defined in order for applications written in separate programming languages to easily and transparently coexist with each other within the .NET Common Language Runtime (CLR).

In order for all the languages to build CLS-compliant applications, there has to be a standard set of language features, which requires additional keywords to be added to each of the .NET languages. For example, the exception handling done in a .NET application is different from what is done in a standard C++ application. The CLR provides try/except/finally functionality, whereas C++ has try/catch. Although the functionality is basically the same, differences do exist. Therefore, new keywords are needed so the compiler can generate the common language calls for .NET.

Table below shows a list of all these new keywords with a description of each.

New Keywords for the .NET Framework in VC++ .NET.
Keyword Description
__abstract Declares an abstract class that cannot be instantiated directly. It must first be derived from, and the new class must provide implementations for any pure virtual methods.
__box Creates a copy of a __value class on the CLR heap.
__delegate Declares a reference to a unique method of a managed class. This is typically used for callback functions, where a pointer to a function is required.
__event Declares an event method in a managed class.
__finally Declares a finally block for a try block. The finally block is called all the time before the except block when an exception is caught, and even if an exception is not thrown.
__gc Declares a managed class type.
__identifier Allows a C++ keyword to be used as an identifier. This is useful when you're accessing external classes that may use a C++ keyword as an identifier.
__interface Declares an interface.
__nogc Declares a native C++ class that is not garbage-collected and is allocated on the standard C++ heap. This keyword is not required because the compiler defaults to __nogc if __gc is not specified.
__pin Prevents an object of a managed class from being moved in memory by the CLR during garbage collection.
__property Declares a property member in a managed class.
__sealed Prevents a class declared with the __gc specifier from being a base class or a method from being overridden in a derived class.
__try_cast Performs a cast on a pointer or throws an exception if the cast fails.
__typeof Returns the system type of a class, the value type, and so on.
__value Declares a value type. This is similar to standard structures in C++.

Of the new keywords, the __gc keyword is probably the most noteworthy. By declaring a type with the __gc keyword, you activate the .NET Framework functionality, such as interoperability and garbage collection, for that type. The following code example shows how a class is declared with the __gc keyword:

__gc class MyClass
{
private:
   int m_nValue;

public:
   int GetValue() {return m_nValue;}
};

It is also possible to declare arrays, pointers, and interfaces with the __gc keyword. Doing so specifies that the value works with the managed heap in the .NET Framework. For example, an array declared as shown here creates the array on the .NET heap and its memory is garbage-collected:

Int32 myarray[] = __gc new Int32[10];

When a pointer is declared with the __gc keyword, it is then free to point into the .NET heap. Furthermore, once the pointer is declared, the compiler takes care of initializing the contents of its memory block to zero. Pointers are declared as shown in the following statement:

Int32 __gc* pMyInt;

Other keywords that are useful and commonly used are __property, __event, and __finally. As you work through following sections, you will see uses for the other keywords shown in the above table.


Creating User-Defined Attributes

Attributes provide several uses and advantages that you will learn about in a later hour's lesson. Visual C++ .NET provides the ability to not only use the predefined attributes, but also to create your own.

Using the attribute keyword, you can create your own attributes to use within your applications. The following code segment shows how to use the attribute keyword to declare a class as an attribute that you can apply to classes:

[ attribute(Class) ]
public __gc class MyAttrbute
{
public:
   MyAttribute() {...}              //TODO: Define code for constructors
   MyAttribute( int nValue ) {...}
};

Declaring an attribute that you can apply to method parameters is done by replacing the Class specifier with Parameter, as shown in the followingI~user-defined attributes;creating> code segment:

[ attribute(Parameter) ]
public __gc class MyAttribute {...}

Pragmas Compiler and Linker Features

There are some other miscellaneous keywords and features added to the VC++ .NET compiler and linker that make writing code for the .NET Framework possible. These features include new pragma keywords, preprocessor directives, and compiler and linker flags.

Using New Pragmas

Two pragma statements make it possible to write new .NET applications that utilize existing legacy code. The first pragma, managed, tells the compiler that the code enclosed within the pragma should be compiled as managed .NET code. This pragma is used when .NET Framework code appears within your legacy C++ applications.

The second pragma, unmanaged, does the opposite: It tells the compiler the code within the pragma should be compiled as unmanaged or regular C++ code. When writing a .NET application in VC++ .NET, you can switch back to the standard C++ compiler for part of the application with this pragma. You will learn about the issues involved with mixing managed and unmanaged code within an application in a later hour's lesson. The code in below shows the use of the managed and unmanaged pragmas.

Use of #pragma managed and #pragma unmanaged Within Visual C++ .NET
 1: // must be compiled with /clr compiler option
 2:
 3: // for managed code
 4: #using <mscorlib.dll>
 5:
 6: // for use with the unmanaged code
 7: #include <stdio.h>
 8:
 9: //Managed code by default
10: void ManagedFunction(void)
11: {
12:    System::Console::WriteLine("Managed function.\n");
13: }
14:
15: // turn off managed code
16: #pragma unmanaged
17:
18: void UnmanagedFunction(void)
19: {
20:    printf("Unmanaged function.\n");
21: }
22:
23: // turn managed code back on
24: #pragma managed
25:
26: void main()
27: {
28:    ManagedFunction();
29:    UnmanagedFunction();
30: }

As you can see from this example, it is possible to create an application with mixed code and control the compiler with the managed and unmanaged pragmas.

Another very useful pragma that you should use in virtually every application you create is once. This pragma placed at the top of any file tells the compiler to only load the file once. This is extremely useful in header files to keep them from being included more than once through redundant references. It eliminates the practice of using a definition as a tag and checking for that definition within the header. The following code shows an example of how you would previously enforce the inclusion of a file only once:

#ifndef MY_INCLUDE
#define MY_INCLUDE

// The include file contents

#endif

This code is now replaced with the #pragma once statement, as shown in the following code segment:

#pragma once

// The include file contents

Including External Assemblies for Use

Writing managed C++ code for the .NET Framework requires you to use other assemblies (usually DLLs) in order to provide the basic features of the .NET Framework. It is also common to include your own assemblies or third-party ones to provide additional functionality.

Specifying what assemblies your application uses is done with the #using preprocessor directive. It is very similar to the #include directive, except that it doesn't include a source file. Instead, it actually includes the definition of the assembly, known as the assembly manifest. This manifest describes the namespaces, types, enumerations, and methods defined for use within the assembly.

After specifying which assemblies your code will access, you have to specify which namespaces within those assemblies you plan on using. This is accomplished with the using keyword. Without these declarations, anything you use from an included assembly must be fully referenced with the namespace. For example, if you use the MyComponents.DLL assembly, which includes a Simple namespace with a SimpleClass type, the fully qualified reference is MyComponents.Simple.SimpleClass. If your code references this type more than a few times, it is better to use a namespace. The following code shows an example of how to use the using keyword:

#using <mscorlib.dll>
#using <System.dll>
#using <MyComponents.dll>

using namespace System;
using namespace System::ComponentModel;
using namespace MyComponents::Simple;

Using New Compiler Options

There are a few new compiler options for writing managed .NET code in Visual C++ .NET. However, only one option is required to actually compile an application as a .NET Framework application: /clr.

The /clr option tells the compiler to compile the code for the common language runtime (CLR). All code within the project defaults to managed code unless you specify otherwise with the pragma described earlier.

The /clr option also has an optional :noassembly directive that specifies that the assembly manifest that describes the assembly should not be inserted into the resulting output file. When an assembly manifest is not inserted into the file, the default file extension produced by the compiler is .netmodule, and it can only be used when the output file type is a DLL. The /NOENTRY linker option described in the next section must also be used with this directive.

The other two new compiler options deal with the #using keyword described earlier. The first is the /AI option, which allows you to specify a search path for the files included in your application with the #using keyword.

The second switch, /FU, replaces the #using keyword by telling the compiler to use a filename within the application. Therefore, you don't have to explicitly use the files within your source. In order for this option to work, you must turn off the Force #using property in the compiler settings for the project.

Using New Linker Options

The new linker options allow you to customize the linking of your managed .NET Framework modules. The first, /NOASSEMBLY, produces a module that is not an assembly by itself, but can be added to an assembly. This option is redundant with the /clr:noassembly directive described earlier and has the same effect.

The /ASSEMBLYMODULE:filename linker option is used when you have a module that is not part of an assembly. This option binds the module to the specified assembly. Although the code within the assembly that the module is bound to cannot access the module code, any application that uses the resulting assembly can access everything within the assembly.

The last link option, /ASSEMBLYRESOURCE:filename, allows you to bind a .NET Framework resource file to an assembly. These resources are then accessed with the System.Resources namespace classes. The resource file has a .resources extension and is generated by the Resource File Generator (RESGEN.EXE) or in the development environment.


Summary

In this tutorial you learned about the new special features in Visual C++ .NET that allow it to create managed code for the .NET Framework. Other new features have been added to the language, compiler, and linker to provide enhancements and support for 64-bit Windows development. However, they are not required for .NET development.

As you read through the other hours, you will work with the new language features you've become familiar with in this hour, and you will see how they fit into the bigger picture of creating .NET Framework applications and working with legacy Visual C++ applications.