Unmanaged and Managed Code Together

   

One thing that has plagued the C++ language and is often brought up in critique circles isn't the fault of the language but rather is due to developer errors. Memory allocation and pointers contain several advantages, but when used incorrectly, they can lead to slow system degradation. If a program that is running continuously allocates but never frees that allocated memory, you'll soon see the system on which the application is running come to a grinding halt. The .NET Framework and its garbage-collection mechanism were designed to prevent this from happening. Objects are allocated by the developer, but the act of releasing that memory once an object is destroyed is left up to the garbage collector. However, some C++ developers feel this is removing some of the power of the language by adding an extra layer that could easily be developed by them. Garbage-collection arguments will probably go on forever, but the fact remains that each method of memory allocation and deallocation has its advantages and disadvantages.

Even though your application runs within the common language runtime, you still have the ability to run portions of your code in an unmanaged environment. You'll recall that to declare a class as managed you use the __gc keyword. If that keyword is absent from the class declaration, the class by default is an unmanaged class. Furthermore, to remove any inconsistencies within your code, you can also use the __nogc keyword to designate a class as unmanaged.

For this lesson, you will be creating an unmanaged C++ class and using it within a managed application. To begin, select New, Project from the File menu. Select the Visual C++ Projects project type and select the Managed C++ application project template. Give your project the name PInvoke and click OK to create the project.

Open the PInvoke.cpp file and create an unmanaged class named CSystemTime by preceding the class keyword with the __nogc keyword. Believe it or not, that is all you need to do to create an unmanaged class. You are free to add member functions and member variables, with one exception: Even though you can use .NET objects within a member function, you cannot declare any .NET objects as member variables unless they are wrapped with the type-safe wrapper template gcroot. Because the String object is easy to use, you will create a String member variable within your unmanaged class. In order to use the gcroot template, you must include the vcclr.h header file. Place the preprocessor directive for vcclr.h to include it in your project, as shown on line 4 of Listing 22.1.

To include a .NET object as a variable in an unmanaged class, you must use the gcroot object as just mentioned. Because this is a template, it expects a type as the template parameter. In this case, you are using a String object. Declare a String* member variable using the gcroot template, as shown on line 24 of Listing 22.1. Within the constructor of your class, create a new instance of the variable just as you would do with a regular String object. In order to test the class, create a public member function named SayHello that accepts no parameters and returns void. Within that function body, output the string variable you created earlier using Console::WriteLine.

Listing 22.1 Creating an Unmanaged Class Within a Managed Application
 1: #include "stdafx.h"  2:  3: #using <mscorlib.dll>  4: #include <vcclr.h>  5:  6: #include <tchar.h>  7:  8: using namespace System;  9: 10: __nogc class CSystemTime 11: { 12: public: 13:     CSystemTime() 14:     { 15:         m_strHello = new String("CSystemTime says..."); 16:     }; 17: 18:     void SayHello() 19:     { 20:         Console::WriteLine(m_strHello); 21:     } 22: 23: private: 24:     gcroot<String*> m_strHello; 25: }; 26: 27: // This is the entry point for this application 28: int _tmain(void) 29: { 30:     CSystemTime* pSysTime = new CSystemTime; 31: 32:     pSysTime->SayHello(); 33: 34:     // comment the following line to create a memory leak 35:     delete pSysTime; 36: 37:     return 0; 38: } 

Now that you have created your unmanaged class, you can use it within managed code. Using an unmanaged class is exactly the same as using a native C++ class. Within your _tmain function, instantiate an instance of the CSystemTime class and call the SayHello function. You aren't finished, however. Because you are using an unmanaged class, you must make sure you delete the memory that was allocated, as shown on line 40 of Listing 22.1.

You can now compile and run your application. You'll see that the managed code works with your unmanaged class just fine. Your output should appear similar to what's shown in Figure 22.1.

Figure 22.1. Calling unmanaged code within a managed application.

graphics/22fig01.jpg


   
Top


Sams Teach Yourself Visual C++. NET in 24 Hours
Sams Teach Yourself Visual C++.NET in 24 Hours
ISBN: 0672323230
EAN: 2147483647
Year: 2002
Pages: 237

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net