This final section of the book addresses interoperability between .NET code and the wider world of Microsoft Windows applications. As you can imagine, .NET code can't live in a vacuum and will have to call (and be called from) code outside the .NET world. Microsoft has put a considerable amount of work into ensuring .NET applications can work simply and effectively with existing Windows code.
This chapter describes the functionality .NET provides for interoperating between managed code (which is executed by the common language runtime) and unmanaged (or native ) code . In addition to exploring the differences between managed and unmanaged code, this chapter will introduce the Platform Invoke mechanism by which .NET code can interact with unmanaged code. If you've had any experience with using Java JNI (Java Native Interface) to interoperate between Java and C code, you'll see that Platform Invoke is much easier to use.
Interacting with unmanaged code will often involve calling Windows APIs or other functions provided in DLLs. As many of these are C or C++ functions, it is often necessary to pass or receive pointers. Because of the way .NET handles memory, passing pointers to and from unmanaged code can be tricky. To help you accomplish these tasks , this chapter provides an overview of .NET memory management and discusses the language-specific features within C++ and Microsoft Visual C# that are used to work with pointers.
This chapter looks at the basics, and the following chapter will delve more deeply into issues surrounding interoperability and introduce advanced topics.
At times, I'll use the term legacy code . This word isn't intended to be pejorative. Although it's often used to mean old-fashioned, out-of- date code , I'm using the term to mean code you have to use as-is, without being able to rewrite it in .NET. An ActiveX control, for example, might have been written last week, but from the point of view of the .NET programmer, it is legacy code if they have to use it in a .NET project.