Transcription of Building a Managed Wrapper with C++/CLI - …
1 1 Building a ManagedWrapper with C++/CLIB onusChapter 2 Act in haste and repent at leisure; code too soon and debug KenningtonThe Microsoft .NET platform provides many tools and libraries to support rapidapplication development, code robustness, strict type safety, and much , in order to take advantage of the features provided by this excellent platform, you must transition some, or all, of your existing code onto it. Somecompanies have the resources to port their existing solutions to .NET, but many com-panies(especially in game development) cannot spare the extra resources tomigrate such a significant amount of work to the .NET platform. Typically, thelargest amount of code for a game development studio is for the engine and itsrelated strongly sought after feature for custom tools and editors is direct integrationwith the engine instead of writing a watered-down version of the engine for func-tionality purposes.
2 Exposing an engine to a toolset is quite difficult and problem-atic, especially when the engine is written in unmanaged C++ and the toolset iswritten in Managed C#. It is not realistic to port the entire engine to the .NETframework for a number of reasons, such as performance and development , tools developers are starting to see significant productivity and maintainabilitybenefits from writing tools with .NET. The real trick is figuring out how to makeboth sides of the development team happy: tools developers and engine this chapter, I first introduce C++/CLI ( Managed C++), then describe what itis and what it is used for. I then introduce some rudimentary keywords and con-structs used for working with Managed code.
3 Afterwards, a simple unmanagedcode base is introduced and a Wrapper built around it. The final part of this chap-ter shows how to wrap an unmanaged code base into a Managed assembly withC++ to Managed C++ ( C++/CLI )The .NET framework provides a set of extensions to the Visual C++ compiler andlanguage to provide the ability to compile Managed code and access the power andfunctionality of the .NET class framework. These extensions are known asC++/CLI (formerly known as Managed Extensions for C++), and include specialkeywords, attributes, preprocessor directives, and pragmas that facilitate theunderstanding of Managed code. In addition to syntactical extensions, C++/CLIalso offers a variety of additional compiler and linker settings to support managedcompilation and the CLR.
4 Even with the extensions, C++/CLI still follows thesame rules for C++ syntax and keywords, except it follows .NET rules for typesand architecture. C++/CLI can be thought of as a language within a language. NoteAs of .NET , Managed Extensions for C++ has become known as C++/CLI and offers a redesignof the old syntax due to feedback from the development community. This chapter summarizes thenew syntax and everything else inherited from the update to C++/CLI . You can still use the old syn-tax and functionality with the /clr:oldSyntaxswitch, but C++/CLI will be the only supporteddialect moving forward, so it is important that you consider this ++/CLI provides mechanisms that allow Managed and unmanaged code to co-exist and interoperate in the same assembly or even in the same source file.
5 Noother language targeting the .NET runtime offers the interoperability features sup-ported by C++ continuing on into syntax, it is important to trace a mapping betweennative type names and their equivalent Managed representations when compiledas Managed code. Functions and methods are fairly automatic to wrap, but nativetypes can present certain challenges. Value types are fairly standard, but , for example, does not directly map to a Table shows a listing of native types and their equivalent representationsin Managed code. If you are using the native type identifiers in Managed C++,then you are actually aliasing the appropriate Managed Chapter 2 Building a Managed Wrapper with C++/CLI2 Introduction to Managed C++ ( C++/CLI )3 This chapter only covers a small subset of the C++/CLI language.
6 If you want toacquire comprehensive understanding of the language, I suggest you get theC++/CLI Language Specificationfile from Microsoft s Web of Extended SyntaxThe syntax for the C++/CLI language is a couple hundred pages in length, so cov-ering the entire language is unrealistic for this chapter. Even covering the changesfrom Managed Extensions for C++ to C++/CLI is significant in length, so thischapter will merely focus on the most important and commonly used changeswith the new language. If you are new to C++/CLI but have prior experience withManaged C++, I recommend you download the C++/CLI Language Table Equivalents of Native TypesNative TypeManaged char char double int long int long __int64 __int64 short short you have never worked with Managed C++, I still recommend you downloadthe specification and do not worry about learning the old syntax.
7 Standard syntaxrelated to unmanaged C++, carried over to C++/CLI , will not be covered in thissection (such as type accessibility with the publicand privatekeywords).Reference HandlesPerhaps one of the most confusing elements of the old Managed C++ syntax wasthe sharing of the *punctuator for unmanaged pointers and Managed syntax for C++/CLI has cleaned up many aspects of the language, includingthe introduction of reference handles. Reference handles are Managed referencesto objects that are located on the Managed heap and are expressed with the ^punc-tuator (pronounced cap ). Handles are completely different from pointers, whichjust reference a particular location in memory. Pointers are unaffected by thegarbage collector, but this also means that the garbage collector cannot optimizememory storage.
8 Reference handles point to the object on the Managed heap, somemory can move around and handles will update accordingly. Developers mustexplicitly delete memory when using pointers, whereas explicitly deleting is optionalwhen using reference following code shows a simple way to create a string, referenced by a ^ myString = Hello World ;Just as newreturns a pointer,gcnewreturns a reference handle. Using gcnewoffers aneasy way to differentiate between Managed and unmanaged instantiations. Thefollowing code shows gcnewreturning a reference ^ myObject = gcnew Object();NoteHandles are type-safe, which means you cannot cast a handle to a void^.In Managed Extensions for C++, reference types were prefaced with the __gckey-word.
9 In the new C++/CLI language, the __gckeyword is replaced by either refclassor ref struct, depending on the type needed. The following code shows howto declare a Managed class MyClass{// .. Class implementation here}; bonus Chapter 2 Building a Managed Wrapper with C++/CLI4 Similarly, value types were originally prefaced with the __valuekeyword, but nowyou use either value classor value struct,depending on the type : abstractThe abstract is context-sensitive and is used to declare that a member can only bedefined in a derived type and that a class cannot be instantiated directly. This key-word is also valid when compiling native following code will generate a compile error (C3622) when executed becauseMyBaseClassis marked as class MyBaseClass abstract{public:virtual void SimpleFunction() {}};int _tmain(){MyBaseClass^ baseClass = gcnew MyBaseClass;}Also, a similar compile error (C3634) will be generated for each of the two func-tions in the following class when instantiated directly.
10 One of the methods ismarked as abstract, while the other method is declared to be pure class MyBaseClass abstract{public:virtual void SimpleMethod abstract () {}virtual void OtherMethod() = 0 {}};NoteDeclaring an abstract function is the same as declaring a pure virtual function. Also, the enclosingclass is also declared as abstract if a member function is declared to be : delegateProgrammers who have worked with C++ should be familiar with function similar mechanism known as a delegate exists in the .NET world. A delegate isIntroduction to Managed C++ ( C++/CLI )5basically a reference type that can encapsulate one or more methods that conformto a specific function prototype. The following code shows how to define a delegate void SimpleDelegate(int number);Next, we will define a class that has a couple of methods conforming to our newdelegate class SimpleClass{public:void SimpleMethod(int number){//.}}