Posts
50
Comments
102
Trackbacks
0
Tuesday, February 07, 2012
Going Native 2012 sessions available for download and streaming

If you missed it, you can now download or stream (whichever you prefer) the sessions from the Going Native 2012 conference. I watched the whole thing and it was fascinating. If you’re new to C++, then some of the sessions are likely to be at a higher level than you may be ready for (though you can certainly watch them if you like). But there are some sessions I think any C++ developer would profit from watching. These are they:

Day 1:

Bjarne Stroustrup - C++11 Style

Stephan T. Lavavej - STL11 – Magic && Secrets

Panel - The Importance of Being Native

Day 2:

Herb Sutter - C++11, VC++11 and Beyond

Chandler Carruth - Clang - Defending C++ from Murphy's Million Monkeys

Panel- Ask Us Anything!

If you are planning to do any multi-threading, then I’d definitely recommend watching Hans Boehm - Threads and Shared Variables in C++11 . For Metro style development, I’d generally recommend using the Parallel Patterns Library (PPL) and the Concurrent Runtime (ConcRT) as they mesh nicely with WinRT’s asynchrony.

Andrei Alexandrescu is a great speaker and his sessions are really entertaining and informative. But it’s likely to be a little while before variadic templates appear in VC++11 (post-RTM but likely in an out-of-band release rather than waiting for VS11 SP1) and they are a pretty tricky topic and the concept of “static if” is a proposal for a future version of the C++ language (but an interesting one and so I’d definitely say go watch it if you have time). They are interesting sessions but not really things for beginners.

Bjarne Stroustrup and Andrew Sutton’s session entitled “A Concept Design for C++” is also interesting but is something that’s still in the research phase of development. It had been proposed for C++11 but was dropped because (as I understand it) they didn’t feel that it was ready to be included in the standard just yet. (This is an area where I personally think C++ could take a lesson from C#. I think C++ would benefit a lot from a purely abstract type (something similar to if not the same as C#’s interface type) with its own keyword designating it as such (thereby adding developer-friendly guarantees that the type was abstract and thus removing the need to use multiple class inheritance for such reasons). This in turn would open the door to a mechanism for templates that would be similar to C#’s constraint system for C# generics. Maybe there are good reasons not to do this; I’m not a language designer. But from an outsider’s perspective, I think C# got this one right.)

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Tuesday, February 07, 2012 10:27 PM | Feedback (0)
Thursday, February 02, 2012
C# to C++ – A Somewhat Short Guide

Last updated: 2012-02-02

This is a big post – over 12200 words – and so I’ve decided to make it available as a PDF download, which you can get here:

http://www.bobtacoindustries.com/Content/Devs/CsToCpp-ASomewhatShortGuide.pdf

It has bookmarks for easier navigation along with a Table of Contents and page numbers.

I expect that I will revise this from time to time and welcome any suggestions, feedback, and (especially) corrections. If so I will update the Last updated field at the top and will create a revised PDF as well. I hope this proves useful.

For those interested, the sessions from the GoingNative 2012 conference will be streaming live today (Feb 2) and tomorrow on Channel 9: http://channel9.msdn.com/posts/Announcing-the-GoingNative-2012-Full-Schedule . Sessions will also be available for download shortly after the show ends (I’d guess within 24-48 hours, but that’s just a guess). It looks fascinating so definitely check it out! (I know I will be watching it.)

 

Introduction

This is a somewhat short guide to the important things to know if you are a C# programmer and find yourself needing or wanting to work in C++, for example to create Metro style games for Windows 8 using C++ and DirectX. In fact, this guide is written with that goal in mind so it's not necessarily a universal guide for all platforms and purposes.

This guide is also going to be fairly utilitarian and pithy, with code standing in place of elaborate commentary. I'm expecting that you know how to program already and have a good understanding of C# (or of some sort of imperative, object-oriented language at any rate).

I'm also assuming you are fairly handy with navigating the MSDN library. Its Bing search box is really awesome; if you haven't used it before, do give it a try. I like how the search is tailored to not just MSDN but also other great programmer sites like the Stack Exchange sites, CodeProject, CodePlex, etc.

I'm sprinkling a fair bit of code throughout as I said above. This is both to show you a (pseudo) real example of something and also to help illustrate words with code so that each will hopefully help to clarify the other.

Simple test programs

I highly encourage you to create a simple scratch program that you can mess around with. I do this all the time with various languages and frameworks in Visual Studio. I normally append "Sandbox" to the name so that I know it's something I am just playing around in. I tend to comment code out when done with it rather than delete it since I may want to look at it again in the future (perhaps to see a specific syntax that I puzzled out but haven't used in a while or maybe for some technique I was trying that I now want to use in a real project). If the code in question might be a bit confusing later on, I try to add some comments that will help me understand it. It's helpful to use a descriptive naming scheme for variables, classes, and functions (though I admit that I'm not too good about this in my sandbox apps). If a project gets too full or busy then I might use regions to hide a section of code or I might create another project or even another solution that will serve as a clean slate.

While developing this guide I've mostly been working in a project called CppSandbox developed in VS 2010 Ultimate and checked in VC++ 2010 Express. It's just a C++ Win32 Console Application (without ATL or MFC but with a precompiled header). This has let me test things like thread local storage duration. The C++/CX stuff can only be tested on using the VS11 preview on Windows Developer Preview (and, presumably, the next preview release of Windows 8, which is due towards the end of this month (Feb 2012)). For everything else you can use either VS 2010 Professional or greater or VC++ 2010 Express (available free here: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express ).

The major feature not present in VC++ 2010 is the ability to compile 64-bit applications. I'm not going to be touching on that here and I don't know whether that will be possible with the free versions of VS11 when they are released. I did do some tests with it in VS 2010 Ultimate just so I could examine the ASM it generates (out of curiosity). The main reason I developed in VS 2010 Ultimate is that it lets me work on multi-language projects at the same time such that I could write out a bit of test code in C# in a Console project and then duplicate it in C++. That wound up not being a big factor since I changed tactics but I already had the sandbox project so I just kept working with it.

That's enough chit-chat, I think. Let's get down to business!

Fundamental types

The C++ standard only requires that the integral types and floating point types each be at least as large as their next smallest counterpart. So when is a long not a long? When one long is a C# long (8 bytes) and the other is a Visual C++ long (4 bytes – same as an int). A Visual C++ 'long long' is 8 bytes. Microsoft has a table of fundamental sizes here:

http://msdn.microsoft.com/en-us/library/cc953fe1.aspx

Note that there are Microsoft-specific integral types that specify sizes exactly, such as __int32 (a 32-bit integer, same as a C# int), __int64 (a 64-bit integer, same as a C# long), etc.

The float and double types are the same sizes as in C# (32-bit and 64-bit, respectively). There's a type called 'long double' but in Visual C++ it is the same as a double so I don't recommend using it to avoid confusion.

Objects – class vs. struct vs. union

The difference between a class and a struct is simply that a struct's members default to public whereas a class's members default to private. That's it. They are otherwise the same.

That said, typically you will see programmers use classes for elaborate types (combinations of data and functions) and structs for simple data-only types. Normally this is a stylistic choice that represents the non-object-oriented origins of struct in C and that makes it easy to quickly differentiate between a simple data container versus a full-blown object by looking to see if it's a struct or a class. I recommend following this style.

In WinRT programming, a struct that is public can only have data members (no properties or functions) and those data members can only be made up of fundamental data types and other public structs (which, of course, have the same data-only, fundamental & public structs only restrictions).

As a terminology note, you'll commonly see structs that only have data members referred to as plain old data ("POD") structs.

You will sometimes see the friend keyword used within a class definition. It is followed by either a class name or a function declaration. What this does is give the class/function specified access to the non-public member data and functions of the class. It's probably not a great thing to use very often (if ever), but if you decide you need it for some reason and that refactoring your code would be impractical, it's there.

Multiple inheritance

C++ classes can inherit from multiple base classes. This is called multiple inheritance. I strongly recommend that you only use multiple inheritance as a workaround for the fact that C++ has no separate "interface" type. Design classes in the same way that you would in C# (i.e. with either no (explicit) base class or else with just one base class). When you want an interface, create an abstract class and inherit from that as well. To avoid trouble, have your interface classes only define pure virtual member functions. The syntax for such is to follow its parameter list with '= 0'. For example:

class IToString

{

public:

    // Require inheriting classes to define a ToString member function

    virtual std::wstring ToString() = 0;

};

 

 

class SomeBaseClass

    : virtual public IToString

{

public:

    SomeBaseClass()

        : m_count()

    {

    }

 

    ~SomeBaseClass() { }

 

    std::wstring ToString() { return std::wstring(L"SomeBaseClass"); }

 

    void AddToCount(int val) { m_count += val; };

 

    int GetCount() { return m_count; }

 

protected:

    int m_count;

};

 

 

class SomeClass

    : public SomeBaseClass

    , virtual public IToString

{

public:

    SomeClass() { }

 

    ~SomeClass() { }

 

    void SubtractFromCount(int val) { m_count -= val; }

 

    std::wstring BaseToString() { return SomeBaseClass::ToString(); }

 

    std::wstring ToString() override { return std::wstring(L"SomeClass"); }

};

You'll notice that we marked the inheritance from the "interface" class with the virtual keyword when inheriting from it. This prevents a bizarre, battle of the inheritances from playing out. It'll compile without it (maybe) and if so likely even work right without it. However if you had data members in the class that is inherited from twice, it would wind up creating two copies of those data members (thereby making the class take up more room in memory).

Also, without marking the inheritance virtual, you must implement ToString in SomeClass rather than just inheriting it from SomeBaseClass. Otherwise you would get a compile error complaining that SomeClass is an abstract class wherever you tried to instantiate it and errors about being unable to pick between SomeBaseClass::ToString and IToString::ToString whenever you tried to call SomeClass's ToString member function. So the compiler issues warnings to you if you don't have those virtual markers because it's not sure that you really wanted two implementations of IToString.

Note that if you left off the override keyword from the definition of ToString in SomeClass, you would get a compiler warning about how SomeBaseClass already provides you with an implementation of IToString::ToString. By telling it we want to override any other definitions we make it clear that we want to override it and didn't just accidentally add it.

SomeClass's BaseToString member function shows the syntax you use when you want to call a member function of a class you've inherited from. It's the same syntax you'd use if you were calling a static member function, but the compiler knows that it's not a static and makes sure to translate things correctly so that it'll call SomeBaseClass's ToString when you use that syntax inside a derived class like that.

Union

A union is a data type that can't inherit from other classes or be a base class for other classes to inherit from. (In the last sentence, class refers to 'class', 'struct', and 'union' which are considered to be mandatory class-keys that specify the particular behavior of a class type). A union is made up of data members and (optionally) functions. Only one of its non-static data members can be active. This lets it fill several different roles at different times. It can also open the door to potential micro-optimizations.

There's a lot more that could be said about unions, but I have no intention of explaining them here. Unions are complicated to explain and I don't personally find them helpful. I see them as being part archaic and part advanced. You can get by just fine without them and if you really need to know more you can read up about them elsewhere. If there's sufficient desire, I'll reconsider my decision and perhaps either add more about them here or else write about them elsewhere or at least link to someone who has.

C++ constructors

C++ has four types of constructors: default, parameterized, copy, and move.

A default constructor is a constructor that can be called without an argument. Note that this includes a constructor that has parameters, provided that all the parameters have been assigned default values. There can only be one of these.

A parameterized constructor is a constructor which has at least one parameter without a default value.

A copy constructor is a special type of constructor which creates a copy of an existing class instance. There are two potential types of these (one const, one non-const) but normally you only write a const version. The compiler will typically implicitly create one for you if you don't (there are specific rules governing this). I always find it better to be explicit rather than rely on rules I would have to look up and read carefully.

A move constructor is a special type of constructor which creates a new class instance that moves the data contents of another class into itself (thereby taking over the data). They have various uses, but an easy to understand example is where you have a std::vector<SomeClass> (the C# equivalent is List<SomeClass>). If you do an insert operation and there is no move constructor (think a List<T> where T is a value type) then every object that has to be moved must be copied. That churns a lot of memory and wastes a lot of time. If there is a move constructor then everything goes much faster since the data can just be moved without copying. There are some instances where the compiler will implicitly create a move constructor for you. You should be explicit about this since you could easily wind up accidentally triggering a circumstance that causes one to suddenly be created/not created whereas previously it was not created/created (i.e. it flips behavior). You could in theory have both a const and a non-const move constructor, but a const one makes no sense at all.

With both copy and move constructors, if you provide one you should also provide the equivalent assignment operator overload.

We'll examine a class with all types of constructors now.

The following is the header file of a class named SomeClass. It includes the definition as well, though normally you would put any non-inline member function definitions in a separate CPP file. The class doesn't do anything of value but it does demonstrate a variety of things, such as all constructor types, a destructor, the use of checked iterators to safely copy data, and the use of some helpful Standard Library functions such as swap, fill_n, and copy. It also demonstrates both a static member function and an instance member function (one that is marked const (see Const-Correctness below)).

#pragma once

 

#include <string>

#include <algorithm>

#include <iterator>

 

using namespace std;

using namespace stdext;

 

class SomeClass

{

public:

    // Default constructor with default value parameter.

    SomeClass(const wchar_t* someStr = L"Hello");

 

    // Copy constructor.

    SomeClass(const SomeClass&);

 

    // Copy assignment operator.

    SomeClass& operator=(const SomeClass&);

 

    // Move constructor.

    SomeClass(SomeClass&&);

 

    // Move assignment operator.

    SomeClass& operator=(SomeClass&&);

 

    // Constructor with parameter.

    SomeClass(int, const wchar_t* someStr = L"Hello");

 

    // Destructor.

    ~SomeClass(void);

 

    // Declaration of a static member function.

    static void PrintInt(int);

 

    // Declaration of an instance member function with const.

    void PrintSomeStr(void) const;

 

    // Declaration of a public member variable. Not per se a

    // good idea.

    std::wstring                            m_someStr;

 

private:

    int                                m_count;

    int                                m_place;

 

    // This is going to be a dynamically allocated array

    // so we stick it inside a unique_ptr to ensure that

    // the memory allocated for it is freed.

    std::unique_ptr< long long[] >     m_data;

};

 

 

// Default constructor definition. Note that we do not

// restate the assignment of a default value to someStr here in the

// definition. It knows about it from the declaration above and will

// use it if no value is provided for someStr when calling this

// constructor.

inline SomeClass::SomeClass(const wchar_t* someStr)

    : m_someStr(someStr)

    , m_count(10)

    , m_place(0)

    , m_data(new long long[m_count])

{

    std::wcout << L"Constructing..." << endl;

 

    std::fill_n(checked_array_iterator<long long*>(this->m_data.get(), m_count), m_count, 0);

}

 

 

// Copy constructor definition.

inline SomeClass::SomeClass(const SomeClass& other)

    : m_someStr(other.m_someStr)

    , m_count(other.m_count)

    , m_place(other.m_place)

    , m_data(new long long[other.m_count])

{

    std::wcout << L"Copy Constructing..." << endl;

 

    std::copy(other.m_data.get(), other.m_data.get() + other.m_count, checked_array_iterator<long long*>(this->m_data.get(), this->m_count));

}

 

 

// Copy assignment operator definition.

inline SomeClass& SomeClass::operator=(const SomeClass& other)

{

    std::wcout << L"Copy assignment..." << endl;

 

    this->m_someStr = other.m_someStr;

    this->m_count = other.m_count;

    this->m_place = other.m_place;

 

    if (this->m_data != nullptr)

    {

        this->m_data = nullptr;

    }

 

    this->m_data = std::unique_ptr<long long[]>(new long long[other.m_count]);

    std::copy(other.m_data.get(), other.m_data.get() + other.m_count, checked_array_iterator<long long*>(this->m_data.get(), this->m_count));

 

    return *this;

}

 

 

// Move constructor definition.

inline SomeClass::SomeClass(SomeClass&& other)

    : m_someStr(other.m_someStr)

    , m_count(other.m_count)

    , m_place(other.m_place)

    , m_data(other.m_data.release())

{

    std::wcout << L"Move Constructing..." << endl;

}

 

 

// Move assignment operator definition.

inline SomeClass& SomeClass::operator=(SomeClass&& other)

{

    std::wcout << L"Move assignment..." << endl;

 

    std::swap(this->m_someStr, other.m_someStr);

    std::swap(this->m_count, other.m_count);

    std::swap(this->m_place, other.m_place);

    std::swap(this->m_data, other.m_data);

 

    return *this;

}

 

 

// Parameterized constructor definition. Note that we do not

// restate the assignment of a default value here in the definition.

// It knows about it from the declaration above and will use it if

// no value is provided for someStr when calling this constructor.

inline SomeClass::SomeClass(int count, const wchar_t* someStr)

    : m_someStr(someStr)

    , m_count(count)

    , m_place()

    , m_data(new long long[m_count])

{

    std::wcout << L"Constructing with parameter..." << endl;

 

    for (int i = 0; i < m_count; i++)

    {

        m_data[i] = (1 * i) + 5;

    }

}

 

 

inline SomeClass::~SomeClass(void)

{

    std::wcout << L"Destroying..." << endl;

    //// This isn't necessary since when the object is destroyed

    //// the unique_ptr will go out of scope and thus it will be

    //// destroyed too, thereby freeing any dynamic memory that was

    //// allocated to the array (if any).

    //if (this->m_data != nullptr)

    //{

    //    this->m_data = nullptr;

    //}

}

 

 

// Note that we don't have the static qualifier here.

void SomeClass::PrintInt(int x)

{

    std::wcout << L"Printing out the specified integer: " << x << endl;

}

 

 

// But we do need to specify const again here.

void SomeClass::PrintSomeStr(void) const

{

    wcout << L"Printing out m_someStr: " << m_someStr << endl;

 

    // If we tried to change any of the member data in this method

    // we would get a compile-time error (and an IntelliSense

    // warning) since this member function is marked const.

}

Hopefully the above was enlightening. Terms like move constructor and copy constructor are thrown around a lot in C++ so having an example to look at should prove helpful. My goal was not to produce a class that is useful, but one where you could see the declaration patterns of these constructor types and see some ways to implement them (along with the required assignment operator overloads) by using Standard Library functions.

Storage duration

There are four possible storage durations: static, thread, automatic, and dynamic.

Automatic duration

Within a block (one or more lines of code within curly braces), a variable declared

            a) either with no duration keyword or with the 'register' keyword; AND

            b) without using the 'new' operator

has automatic scope. This means that the variable is created at the point at which it is declared is destroyed when the program exits the block. Note that each time the declaration statement is executed, the variable will be initialized. In the following:

for (int i = 0; i < 10; ++i)

{

     SomeClass someClass;

     someClass.DoSomething(L"With Some String");

}

you'll run the SomeClass constructor and destructor ten times (in the order constructor - destructor - constructor - destructor - ... since the current SomeClass instance will go out of scope each time before the condition (i < 10) is evaluated).

(Note that the 'auto' keyword used to be a way of explicitly selecting automatic storage duration. It's been repurposed to function the same as the 'var' keyword in C# as of C++11 (this new meaning of auto is the default in VS2010 and later). If you try to compile something using the old meaning of auto you'll get a compiler error since auto as a type specifier must be the only type specifier. If you've got a lot of legacy code you can disable the new behavior (look it up on MSDN); otherwise stick with the new meaning of auto.)

Dynamic duration

Dynamic duration is what you get when you use either the new operator or the new [ ] operator. While it is fine and even necessary to use dynamic duration objects, you should never allocate them outside of either a shared_ptr or a unique_ptr (depending on which suits your needs). By putting dynamic duration objects inside of one of these, you guarantee that when the unique_ptr or the last shared_ptr that contains the memory goes out of scope, the memory will be properly freed with the correct version of delete (delete or delete [ ]) such that it won't leak. If you go around playing with naked dynamic duration, you're just asking for a memory leak. For more about this see the next topic.

Thread duration

It is also possible to declare certain types of variables as having thread duration. This is similar to static duration except that instead of lasting the life of the program (as we'll see shortly), these variables are local to each thread and the thread's copy exists for the duration of the thread. Note that the thread's copy is initialized when the thread is started and does not inherit its value from the thread that started it.

 C++11 has added a new keyword to declare this ('thread_local') however this keyword is not yet recognized such that you need to use the Microsoft __declspec(thread) syntax to obtain this behavior. For more information, see: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx . See below for a general overview of initialization.

Since this is a bit weird, I created a small sample to make sure I knew what was going on. It's a Win32 Console App tested in VC++ 2010 Express.

Static duration

We finish up with static duration. Primarily because static duration is what you get when none of the other durations apply. You can ask for it explicitly with the static keyword.

Initialization of thread and static duration objects

The details of exactly what happens during initialization of static and thread duration objects are complicated. Everything will be initialized before you need it and will exist until the end of the program/thread. If you need to rely on something more complex than this, you’re probably doing something wrong. At any rate, you'll need to sit down and read the C++ standard along with the compiler's documentation to figure out what's going on when exactly. Some of the initialization behavior is mandatory, but a lot of it is "implementation defined", meaning you need to read the compiler's documentation (i.e. the relevant MSDN pages).

Unwrapped 'new' keywords are dangerous; shared_ptr, unique_ptr, and weak_ptr

If you've worked in a .NET (or other garbage collected) language for a while, you're likely very used to using the 'new' keyword (or its equivalent in your language of choice). Well, in C++ the 'new' keyword is an easy way to create a memory leak. Thankfully, modern C++ makes it really easy to avoid this.

First, if you have a class with a default constructor, then when you declare it, it automatically constructs itself and when it goes out of scope it is automatically destroyed then and there. We discussed this earlier in automatic storage duration.

Next, the language provides two constructs that make it easy to allocate memory and ensure that it is properly freed: shared_ptr and unique_ptr. A shared_ptr is an automatically reference counted container that holds a pointer type (including dynamic arrays such as "new float[50]"). One or more shared_ptrs can exist for the same underlying pointer, hence the name.

Another object is the unique_ptr. You should use this in place of raw pointers except when you need multiple pointers to the same dynamic data (in which case use shared_ptr). Using a unique_ptr ensures that the memory owned by it will be freed when the unique_ptr itself is destroyed (e.g. by going out of scope, via a destructor, or via stack unwinding during an exception).

The last object to consider here is weak_ptr. The weak_ptr exists solely to solve the problem of circular references. If two objects hold shared_ptr references to each other (or if such a thing happens in the course of, say, a doubly-linked list) then shared_ptr's internal reference count can never drop to zero and so the objects will never be destroyed. For such a situation, make one of the references a weak_ptr instead. Weak_ptr is essentially a shared_ptr that doesn't increase the reference count. If you need to use the weak_ptr to access the resource, call its lock function to get a shared_ptr of the resource and then use that. If the object was destroyed before you could get it with lock, you will get back an empty shared_ptr.

The above types are all in the C++ Standard Library's memory header file, which you include as so:

#include <memory>

Notice that there is no ".h" at the end there. That's the way all of the standard library's headers are. If you're curious as to why, see: http://stackoverflow.com/questions/441568/when-can-you-omit-the-file-extension-in-an-include-directive/441683#441683 .

RAII - Resource Acquisition Is Initialization

RAII is a design pattern that, when done properly, enables C++ code to successfully use exceptions without resource leaks. Since C++ doesn't have a GC the way C# does, you need to be careful to ensure that allocated resources are freed. You also need to be sure that critical sections (the equivalent of a lock statement in .NET) and other multi-threaded synchronization mechanisms are properly released after being acquired.

RAII works because of this: when an exception occurs, the stack is unwound and the destructors of any fully constructed objects on the stack are run. The key part is "fully constructed"; if you get an exception in the midst of a constructor (e.g. an allocation failure or a bad cast) then since the object isn't fully constructed, its destructor will not run. This is why you always put dynamic allocations inside of unique_ptr or shared_ptr. Those each become fully constructed objects (assuming the allocation succeeds) such that even if the constructor for the object you are creating fails further in, those resources will still be freed by the shared_ptr/unique_ptr destructor. Indeed that's exactly where the name comes from. Resource acquisition (e.g. a successful allocation of a new array of integers) is initialization (the allocation happens within the confines of a shared_ptr or unique_ptr constructor and is the only thing that could fail such that the object will be initialized assuming the allocation succeeds (and if it doesn't then the memory was never acquired and thus cannot be leaked)).

RAII isn't only about shared_ptr and unique_ptr, of course. It also applies to classes that represent, e.g., file I/O where the acquisition is the opening of the file and the destructor ensures that the file is properly closed. Indeed this is a particularly good example since you only need to worry about getting that code right just the once (when you write the class) rather than again and again (which is what you would need to do if you couldn't use this and instead had to write the close logic every place that you needed to do file I/O).

So remember RAII and use it whenever dealing with a resource that, when acquired, must be freed. (A critical section is another good candidate; successfully getting the enter into the critical section is the acquisition and the destructor would then make sure to issue the leave).

Const-correctness

Const-correctness refers to using the const keyword to decorate both parameters and functions so that the presence or absence of the const keyword properly conveys any potential side effects. The const keyword has several uses in C++. For the first three uses, imagine we have the following variable:

int someInt = 0;

int someOtherInt = 0;

Const pointer

int* const someConstPointer = &someInt;

//someConstPointer = &someInt; // illegal

*someConstPointer = 1; // legal

A const pointer is a pointer that cannot be pointed at something else. You can change the value of the data at the location the const pointer points to. So above, attempting to change the target (even to the same target) is illegal and thus won’t compile but changing the value of someInt by dereferencing someConstPointer is perfectly legal and someInt will now have the value 1.

Pointer to const

const int* somePointerToConst = &someInt;

somePointerToConst = &someOtherInt; // legal

//*somePointerToConst = 1; // illegal

A pointer to const is a pointer to a value that you cannot change via the pointer. You can make the pointer point to something else, though. So above, you can change the target of somePointerToConst. But you cannot change the value of whatever it is pointing to. At least, not via the pointer; you can still set someInt and someOtherInt to have other values either directly or via a pointer that is not a pointer to const. In other words, the const keyword only affects the pointer, not the underlying data.

Const pointer to const

const int* const someConstPointerToConst = &someInt;

//someConstPointerToConst = &someInt; // illegal

//*someConstPointerToConst = 1; // illegal

A const pointer to const is, as you might guess, a pointer to a value that you cannot change via the pointer and that cannot be pointed at something else. It’s an amalgamation of the previous two uses of const.

Constant values

You can also use const to specify that a value in general is constant. It need not be a pointer. For instance you could have

const int someConstInt = 10;

which would create an int that was constant (i.e. unchangeable).

If someInt up above was made a const then the declaration of someConstPointer would be illegal since you would be trying to create a pointer to an int, not a pointer to a const int. You would, in effect, be trying to create a pointer that could modify the value of a const int, which by definition has a constant, un-modifiable value.

Constant member functions

Sometimes you will see a function that is declared and defined with the const keyword after the parentheses in which its parameters (if any) go. For example:

void PrintCount(void) const

{

     wcout << L"m_count = " << m_count << endl;

}

What this usage of const means is that the function itself will not modify any non-static data members of the class and that it will not call any member function of the class unless they are also marked const.

Mutable data members

 In certain instances you may wish to be able to change a particular data member even within constant member functions. If you mark the data member with the mutable keyword, e.g.

mutable int m_place;

then that data member can be changed even within member functions marked as const.

Summary and const_cast

When you use const to appropriately decorate function parameters, mark class member functions const where appropriate, and mark member data that needs to be changed within member functions that are otherwise marked const, you make it easier to understand the side-effects of your code and make it easier for the compiler to tell you when you are doing something that you told yourself you would not do.

The point of const-correctness is to prevent bugs and to make it easier to diagnose a bug. If you have some instance data member that is getting a completely wrong value somehow, you can instantly eliminate any functions that are marked const from your search since they should never be changing the instance data (unless it’s marked mutable, in which case you know to look at those const functions too).

Unfortunately there’s this thing called const_cast<T> which can ruin the party. The const_cast operator can, in many circumstances, eliminate the "const"-ness of something. It also eliminates any volatile and __unaligned qualifiers. You should really, really try to avoid using const_cast if at all possible. But const_cast does have some legitimate uses (otherwise why include it). If you’re interfacing with old code and/or a C language library that doesn’t follow const-correctness and you know that the function you are calling does not modify a variable that it takes as a non-const parameter, then you can mark the parameter to your function that you want to pass as const and then use const_cast to strip the const-ness from it so you can pass it to that function.

Strings

If you did any C or C++ programming at some point in the past you might remember these char* things that were used for strings. DO NOT USE THEM. ASCII strings and characters (char* and char) have no place in a modern program. The 80s are over, and it's a new, Unicode world.

Generally you’ll work with std::wstring and/or wchar_t* strings. These are the two types that Windows uses for Unicode strings. If you're getting data from the internet, you may well be getting it as UTF-8. This is not the same as wchar_t* or std::wstring. If you need to deal with UTF-8 data for some reason, look around on the web for suggestions.

Sometimes in Windows you’ll see the _TCHAR macro used. If you’re ever writing code that needs to run on Win 9x, use the _TCHAR system. Since I’m presuming that you’re learning C++ to use current (D3D11) DirectX technologies, most (if not all) of which don’t even exist pre-Vista, I prefer to work directly with wchar_t and std::wstring since that way macros don’t obscure function parameters in IntelliSense.

C++ recognizes several prefixes for string literals. For wide character strings (the two types above), the prefix L is used. So

const wchar_t* g_helloString = L"Hello World!";

creates a new wide character string. The wchar_t type is used for Unicode strings (specifically UTF-16).

The standard library’s std::wstring is a container for a wchar_t* string. It provides functions for mutating the string and still lets you access it as a wchar_t* when needed. To create one you would do something like this:

std::wstring someHelloStr(L"Hello World!");

If you are using std::wstring (which you should for any mutable strings you create) when you need to get the pointer from it to pass to a function that requires a const wchar_t* then use std::wstring’s data function. (If it needs a non-const wchar_t* then ask yourself whether or not you can accomplish what it is proposing with wstring's functionality instead. If not then you need to create a copy of the data using something like the wcscpy_s function (in wchar.h). Beware of memory leaks.)

Prefix increment vs. postfix increment

If you're coming from C#, you're likely used to seeing the postfix increment operator (i++) most everywhere.

In C++ you'll normally see the prefix increment operator (++i) everywhere.

In both languages the two operators mean the same thing. Postfix means "increment the variable and return the variable's original value (i.e. its value prior to incrementing it)". Prefix means "increment the variable and return the variable's resulting value (i.e. its value after incrementing it)".

To do a postfix increment, the compiler needs to allocate a local variable, store the original value in it, perform the increment, and then return the local variable. (Sometimes it can optimize the local variable away, but not always.)

To do a prefix increment, the compiler can simply increment the variable and return the result without creating an additional local variable.

In truth, the compiler is likely going to be able to optimize away your i++ extra temp allocation if you choose to use the postfix increment (VS 2010 SP1, for example, produces identical assembly code for both (no temp) with a typical ‘for (int i =0; i < 10; i++) { … }’ loop even in Debug configuration where it isn’t going hyperactive with optimizations). Cases where it likely can’t are primarily with custom types that actually implement the increment and decrement operators (see http://msdn.microsoft.com/en-us/library/f6s9k9ta.aspx ) and in cases outside of a ‘for’ loop where you are actually using the value returned by the increment (or decrement) calculation (in which case it definitely can’t since you clearly want either the one value or the other).

In general, using the prefix increment mostly seems to serve as notice that you have spent at least some time learning something about C++ programming.

Collection types

When coming from C# and .NET, you're undoubtedly familiar with the generic containers in C#. C++ also has these sorts of things but the names and methods may not be familiar (they also work a bit differently). Here are some of the more common mappings for collection types typically used in C# game development.

List<T> equivalent is std::vector

The header file include is #include <vector>

A typical way to create one is like this:

std::vector<SomeType> vec;

To add an item to the end of the vector, use the push_back member function. To delete the element at the end use pop_back. For example:

vec.push_back(someItem); // someItem added to the end.

vec.pop_back(); // someItem has now been removed from the end.

To insert an item somewhere other than at the back, use the insert function, e.g.:

vec.insert(begin(vec) + 1, someItem); // someItem added to index 1

// To add to the beginning, you'd just use begin(vec) without the + 1

To remove an item use the erase function, e.g.:

vec.erase(begin(vec) + 2); // The item at index 2 will be removed.

Note that unless you are storing a shared_ptr, any external references to the object will become bad since the destructor will run upon erasing it.

To iterate a vector's items, use code that looks something like this:

for (auto item = begin(vec); item != end(vec); ++item)

{

    // Do stuff with item.

}

If the class you are storing in a vector supports move semantics (i.e. move constructor and move assignment operator) then vector will take advantage of that if you ever need to do an insert or an erase. This can provide a vast speed increase over the copy semantics it would otherwise need to use.

Dictionary<TKey,TValue> equivalent is std::unordered_map

The header file include is #include <unordered_map>

A typical way to create one is like this:

std::unordered_map<int, std::wstring> someMap;

The syntax for adding an item is a little funny (which is why I used real types above rather than made up ones; the key doesn't need to be an int and the value doesn't need to be a wstring). Here's an example of adding an item:

someMap.insert(std::unordered_map<int, std::wstring>::value_type(1, std::wstring(L"Hello")));

Yeah, you need to recapitulate std::unordered_map<TKey,TValue> in order to access its static member value_type (which is an alias for the appropriate constructor of the std::pair type for your map), which you use to insert the key and value. You may want to typedef it so you can shorten it, e.g.

typedef std::unordered_map<int, std::wstring> IntWstrMap;

...

someMap.insert(IntWstrMap::value_type(1, std::wstring(L"Hello");

If you try to use insert with a key that already exists, the insert fails. The insert function returns a std::pair with the iterator as the first item and a bool indicating success/failure as the second, so you can do something like:

if (!someMap.insert(

    std::unordered_map<int, std::wstring>::value_type(

    1, std::wstring(L"Hey"))).second)

{

    wcout << L"Insert failed!" << endl;

}

 

You can also insert items by array notation syntax, e.g.:

someMap[0] = std::wstring(L" World");

If an item exists at that key it will be replaced (unlike with insert). If not, the key will be added and the item inserted there. Note that this is different than in .NET where you would get an exception if you tried to use a key that didn't exist.

To determine if a key exists, use something like this:

if (someMap.find(2) == end(someMap))

{

    wcout << L"Key 2 not found. Expected." << endl;

}

where '2' is the key you are looking for. You could also store the result of the find, check it against end(someMap), and if it's not that, then you know that you have the item.

Indeed, if you want to retrieve an item only if it exists, this is the correct way to do it:

auto itemPair = someMap.find(1);

if (itemPair != end(someMap))

{

    wcout << itemPair->second << endl;

}

If you tried using array notation, e.g.

auto item1Wstr = someMap[1];

you would wind up inserting an item at key '1' if no such item existed, with item1Wstr being the empty wstring that was inserted when you tried to get a key that didn't exist (but does now).

You can also use the at function to get an element at a specific key. If that key doesn't exist, it will throw an exception of type std::out_of_range. For example:

std::wstring result;

try

{

    result = someMap.at(1);

}

catch (std::out_of_range e)

{

    // Do some error handling

    wcout << e.what() << endl;

}

To remove an item, the easiest way is to just call the erase member function with the key you wish to remove.

someMap.erase(1);

You can also use iterators to remove specific items or even a range of items, but in practice these may not be worth the bother. The same caution about references going bad applies here as well as it did in vector. Calling erase will trigger the destructor of any object, whether key or value.

SortedDictionary<TKey,TValue> equivalent is std::map

This is a binary tree rather than a hash map, (which is what unordered_map is). It's used in pretty much the exact same way as unordered_map so read above for usage info.

Others

There are too many collection types to go through them all in such detail. Here are several others you may be interested in:

·         std::list – LinkedList<T>

·         std::stack – Stack<T>

·         std::queue – Queue<T>

On lvalues and rvalues (and xvalues and prvalues)

You may here mention of lvalues and rvalues from time to time. C++ has divided up rvalues into two subtypes: xvalues and prvalues. Which also generated something called glvalues. But we'll get confused if we go any further without clarifying this lvalue and rvalue business. The L and R stand for left and right. An lvalue was a value that could be on the left side of an assignment operator (in other words to the left of an = sign) while an rvalue was a value that could appear to the right of an assignment operator. So given

int x = 5 + 4;

the x would be an lvalue, while 5, 4, and (5 + 4) would all be rvalues.

C++11 has added the concept of rvalue references (which we will discuss shortly). This has created the concept of an expiring value (an xvalue), and in turn the concept of pure rvalues (prvalues).

Prvalues are things like literals as well as the result of a function, provided that that result is not a reference.

An xvalue is an object that's nearing the end of its life; for the most part this means the result of a function that returns an rvalue reference.

An rvalue is either an xvalue or a prvalue.

An lvalue is an object or a function. This also includes the result of a function where the result is an lvalue reference.

A glvalue (a generalized lvalue) is either an lvalue or an xvalue.

If you want to know more (or if the above doesn't make any sense), see:

http://msdn.microsoft.com/en-us/library/f90831hc.aspx and

http://en.wikipedia.org/wiki/Value_(computer_science)

Pointers

A pointer stores a memory address. You can have a pointer to a function, a pointer to a class instance, a pointer to a struct, to an int, a float, a double, … you get the idea. You can declare a pointer in either of the two following ways:

int* pSomePtr;

int *pSomeOtherPtr;

Which you use is purely a style thing; the compiler doesn't care. I use the int* syntax, personally.

Note the naming convention of beginning the name of a pointer with a lowercase p. This helps you instantly recognize that the variable you are working with is (or should be) a pointer. Using this naming style helps prevent bugs and helps make bugs easier to spot when they do crop up.

DO NOT DO THIS:

int* pSomePtr, pNotAPointer;

The pNotAPointer variable is not a pointer to an integer. It is just an integer. The same as if you had said:

int pNotAPointer;

The * must be applied to each variable in a comma separated declaration, which is what makes that declaration evil for pointers. When you use a declaration like the above, it's hard for you (and others who look at your code) to know if you meant for pNotAPointer to be a pointer or just an integer (this is one place where the p naming convention helps). It's also easy to repeatedly overlook the missing * and waste a lot of time trying to find the source of the bug.

Because bugs like that are hard to track down, you should never declare multiple pointers on the same line. Put them on separate lines like this:

int* pSomePtr;      // Definitely a pointer.

int* pSomeOtherPtr; // Definitely a pointer.

int notAPointer;    // Definitely NOT a pointer.

The compiler doesn't care and you will avoid a bad style.

Using pointers

I think the best way to describe using pointers is with documented code. So here's some documented code. Note that some of this code is bad style. I point this out in the comments.

int x;        // Creates an integer named x. Its value is

              // undefined (i.e. gibberish).

 

x = 0;        // x is now equal to zero rather than gibberish.

 

int* pX;      // Creates a pointer to an integer. Its value

              // is undefined (i.e gibberish). If you tried to

              // dereference it you would hopefully crash your

              // program.

 

 

pX = &x;      // pX now points to x. The & here means return

              // the memory address of x. So pX now holds the

              // memory address of x. This & is called the

              // address-of operator. There's also an & that

              // means an lvalue reference and one that means

              // a bitwise AND. You'll learn which is which.

 

*pX = 1;      // Sets x to one. The * here "dereferences" the

              // pointer (i.e. lets you operate on the value it

              // points to rather than on the pointer itself).

              // This * is called the indirection operator.

 

 

pX = 1;       // Bad – this makes the pointer point to memory

              // address 0x01, which (if you are lucky) will

              // cause your program to crash. If not you'll be

              // randomly changing data the next time you use

              // the pointer properly. Worse would be ptrToX++

              // since that is more likely to give you a real

              // memory address. More on that below.

 

SomeClass sc;          // Create a SomeClass instance using

                       // its default constructor.

 

SomeClass* pSc;        // Create a pointer to a SomeClass

                       // instance.

 

pSc = &sc;             // Make pSc point to sc.

 

pSc->PrintSomeStr();   // This and the next statement are

                       // identical. The -> operator means

                       // dereference the pointer then get

                       // the member named PrintSomeStr. This

                       // syntax also works for data members.

 

(*pSc).PrintSomeStr(); // Here we are first dereferencing the

                       // pointer explicitly (*pSc) and then

                       // we're using the . operator to get the

                       // PrintSomeStr member. -> is just clearer

                       // looking.

 

pX = &x;       // Set pX pointing to x again after the mishap above.

 

(*pX)++;       // This increments the value of x by one. It is

               // bad style because of what happens if you forget

               // the parentheses.

 

*pX++;         // This DOES NOT increment the value of x by one.

               // Instead this increments pX by one. It is the

               // exact same result as if you had just written

               // pX++; without having the * in front of it. In

               // other words this changes the memory address

               // pointed to by the pointer, not the value that

               // is stored at the memory address. The * is ignored.

 

*pX = *pX + 1; // This produces the exact same assembly code as

               // (*pX)++; and doesn't have the same bug risk of

               // accidentally forgetting the parentheses. So

               // don't get cute with ++ and --. Just use this

               // instead.

 

int ax[4];         // Declares an array of four integers. The

                   // values are all undefined. But this is

                   // not a dynamic array so you don't

                   // need to wrap it in a unique_ptr or

                   // anything.

 

int* pAx = &ax[0]; // Creates a pointer to the first

                   // element of ax.

 

*pAx = 0;          // Sets the value of the first element of

                   // ax to 0.

 

pAx++;             // Sets the pointer to point to the second

                   // element of ax. Arrays are linear in memory

                   // and the ++ increments the pointer by the

                   // size of one element (in this case the size

                   // of one integer).

 

*pAx = 20;         // Sets the value of the second element of

                   // ax to 20. It effects the same result as

                   // writing ax[1] = 20; would.

 

The above code should give you everything you need to know about how to work with pointers. Whether it's a pointer to int or a pointer to SomeClass doesn't matter. When working with an array, incrementing a pointer to the array's first element with ++ can be a lightning fast way to initialize the array. But if you mess up and run past the end of the array then you'll be corrupting memory (and hopefully will crash your program).

Pointers to class member functions and the 'this' pointer; WinRT event handlers

One common pattern you'll see in WinRT for delegates and event handlers is this:

_someToken = SomeEvent += ref new SomeEventHandler(

    this,

    &SomeClass::MemberFunctionHandlerForSomeEvent

);

In C++, class member functions only exist once in memory no matter how many instances of the class you have. This makes sense since the function itself doesn't change for each instance; only the data that it operates on changes. So all the function needs to know is which data to operate one. As we'll see shortly, the C++ compiler takes care of that for us.

(The same is true in C# actually. Or usually true, anyway. The lone difference is that in C# if you've never run or referenced a method then the method probably won't be in memory since it likely hasn't been jitted yet. Once the program needs the method to be in memory it will be jitted and then it will exist once in memory, just like in C++.)

What the event handler constructor code is doing is constructing a delegate that says "hey you event, when you fire I want you to call me, this instance (ergo you pass the "this" pointer to specify that it should use this instance's data) with the class member function that is located at this memory address (which is what using the address-of operator with a class member function does gives you). It's the combination of instance data and the member function's address in memory that lets the event call the right member function with the right data whenever the event fires. (The bit about the token is just a peculiarity with how you unsubscribe from an event in WinRT when using C++.)

Note that we use the scope-resolution operator, "::", when taking the address of the member function. We use this (rather than . or ->) since what we are after is the address in memory of the member function itself, which as we already said is common to all instances of the class. It will make more sense if we briefly examine what happens when a C++ class member function is compiled.

Behind the scenes, when the C++ compiler compiles a member function it automatically adds a "this" pointer as a parameter to all of the instance member functions of our classes. The "this" pointer is a pointer to a particular instance of the class that the member function is a member of. When you call an instance member function the compiler takes that call and uses that instance's location in memory as the value of the "this" parameter that it added. The member function is wired up to use that "this" pointer to access and operate on the correct instance data.

Knowing all of this should help you understand what the purpose of that syntax for the event handler is. When the event is triggered, in order for the event to call the member function we specified it needs the address of the class instance to pass to the member function as the compiler-added "this" parameter. The only way it can know that is if we tell it what the address is. We do that by passing in "this" as a parameter to the delegate constructor. If you wanted some other class instance, then instead of passing in "this" you would pass in &theOtherInstance as the first parameter (using the address-of operator to get its memory address).

References

References are an attempt to prevent you from shooting your foot off with pointers without removing the ability to pass parameters by reference. They largely succeed but have some inherent limits and are different than .NET references (which really act more like pointers in some ways.

Lvalue references

Lvalue references are a way to create a reference to a value. They are useful for passing a parameter by reference rather than copying by value. Like with pointers, some examples will help explain them.

int x = 0;   // Create an int named x and set it equal to zero.

 

int& rX = x; // Creates an integer reference named rX and sets

             // it to refer to x. From now on rX acts like x.

 

x++;         // x is now equal to one.

rX++;        // x is now equal to two. Note how we didn't need

             // to dereference anything. Once rX is assigned a

             // value it becomes that value for all intents and

             // purposes. You cannot make rX refer to anything

             // else.

 

int &rY; // This is illegal. A reference must be assigned a value

         // when it is created. The only exception is in a

         // function definition since the value is assigned when

         // the function is called or in a class data member

         // definition (though I don't see much utility in having

         // a data member that is a reference, personally).

 

// For the following function, by using a reference, we won't

// invoke the copy constructor when calling this function

// since rSc is a reference to an instance of SomeClass,

// not a separate instance of SomeClass. And we'll only be

// passing the size of a reference (4 bytes in a 32-bit

// program) versus the size of the object (44 bytes using the

// definition of SomeClass from the C++ constructors section).

// So references are your friend. In this case, since we won't

// be changing anything in the SomeClass instance, we mark the

// rSc parameter const.

void DoSomething(const SomeClass& rSc)

{

    rSc.PrintSomeStr(); // Notice that we use the . operator and

                        // not the -> operator.

 

}

Passing parameters by reference (as in the DoSomething function above) prevents memory churning, prevents a constructor from running, and gives us the same behavior as we would expect if we passed a class as a parameter in .NET (i.e. a reference to the same object, not a separate copy of the object).

If you want to pass a copy of the object to a function for some reason then you can. Just leave off the reference marker on the parameter declaration and it will make a copy of the object and pass that copy in when you call the function. If you want to pass a copy to a function that takes a parameter by reference then you need to construct a copy first and then pass the copy in as the parameter when you call the function (since the function definition will only take a reference such that it won't trigger the copy constructor on its own).

Rvalue references

We've already seen rvalue references in the C++ constructors. The move constructor and move assignment operator both dealt in them. They use a syntax that looks like this:

SomeClass&& rValRef;

They are only particularly useful for move semantics and as we've already covered that in the constructors section, there's not much more to say about them here. They are new in C++11 but VC++ 2010 supports them.

Templates

Templates are sort of like .NET generics except that they aren't. They work to accomplish the same goal (generic programming) but do so in a different way. If you are curious to learn more about how .NET generics work, I recommend reading this interview with Anders Hejlsberg: http://www.artima.com/intv/generics.html . I'm going to focus strictly on C++ templates.

Templates are an integral part of the C++ Standard Library. Indeed, the Standard Library is an outgrowth of an earlier project called the Standard Template Library and it's common to see the Standard Library referred to as the STL.

C++ templates allow you to write classes and stand-alone functions which take in type parameters and perform operations on them. Here is an example:

#include <iostream>

#include <ostream>

 

template< class T >

void PrintTemplate(T& a)

{

    std::wcout << a << endl;

}

What C++ does with this is interesting. The compiler will generate a version of PrintTemplate for each type that you call it with and will then use that version for all invocations of PrintTemplate with that data type. So, for example, if you wrote:

int x = 40;

PrintTemplate<int>(x);

the compiler would create a special int version of PrintTemplate, verify that this version of PrintTemplate can in fact work with an int (in this case making sure that int has a << operator defined for it), and if so create everything. Since everything is generated at compile-time it is very fast at execution time. A downside is that you can get some bizarre error stuff in the output window if you tried to pass in a type that doesn't have a << operator defined (e.g. our SomeClass type). And the build will fail, of course.

Indeed, overloaded operators tend to play a big part in template programming. If you take in two types and try to add them, you need to make sure that there's a + operator defined that adds those two types, otherwise it'll be carnage in your output window.

As far as the syntax goes, you just prefix the function or class with template< … > and you are set to go. You can pass as many or as few types as you want. The "class" keyword in there includes classes, structs, and built-in types like int (it likely includes unions too, though I have not tested that). The letter T is just a style convention, the same as in .NET; you can use anything as an identifier.

You can also use concrete types if you like, but then you need to pass a constant value in as the type parameter when invoking the template function/class.

Separate multiple types with a comma.

It's very easy to mess up template syntax and figuring out what you did wrong is a process of looking at the error message, looking up the compiler error number on MSDN, and trying to fix it based on what the error means. If you get stuck, try reading through the MSDN reference documentation on templates: http://msdn.microsoft.com/en-us/library/y097fkab.aspx .

MACROS

Don't create macros. You'll shoot your eye out. See, e.g.: http://msdn.microsoft.com/en-us/library/dy3d35h8.aspx (halfway through the Remarks section). If you're thinking about something that you think might make a good macro, use an inline function instead.

(Mind you, don't intentionally avoid macros that exist within headers that come with the Windows SDK or other SDKs and toolkits you decide to use. Just be aware of the fact that there can be unintentional side effects with macros like in the MSDN example above so avoid code with the potentiality for side effects when using a macro (. Keep it simple.)

Do, however, use other preprocessor features. For example, you should always put

#pragma once

at the top of all header files you write to make sure they are only processed once no matter how many files #include them. That notation is a Microsoft-specific thing, btw. You could also use the ISO-compliant

#ifndef __SOMECLASS_H_

#define __SOMECLASS_H_

 

// Your header file code here.

 

#endif

style. It’s up to you; I use the #pragma syntax since I don’t need to worry about name collision that way. If you use the ISO-compliant syntax and somehow ended up with two files with the same name and forgot, you’ll need to patch up the resulting error from the one file not being included due to the symbol already being defined by the previously included other file. One way to avoid that problem would be to bake in any namespaces or directory paths into the symbol names, e.g. __SOMENAMESPACE_SOMECLASS_H_. You also need to make sure all the header file code is inside the region between the #define … and the #endif if you use ISO-compliant syntax.

C++/CX (aka C++ Component Extensions)

Go watch Herb Sutter's excellent //build/ conference presentation, "Using the Windows Runtime from C++": http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-532T . It's a little over an hour long and will give you good insight not just into C++/CX but also into WinRT and Metro style app development in general.

C++ Component Extensions are a set of language extensions that make it possible to interface with the Windows Runtime and to write components that can be used from languages like C#, VB, and even JavaScript.

The two most common things you will see are the hat symbol '^' which is basically a WinRT pointer and the ref keyword (used in defining a WinRT class and instantiating a new instance of them). WinRT classes are automatically reference counted so you do not need to worry about putting them inside a unique_ptr. Instead you instantiate them like this:

auto someRTClass = ref new SomeRTClass();

The use of 'ref new' is necessary to create a WinRT class instance.

You only need to write a WinRT class if you are writing a WinRT component that's meant to be used as a library in some other application. You don't need to do this for classes that are directly in your game/application (though you can if you want; there's some overhead due to the automatic reference counting but it shouldn't be all that bad).

The following is an example of a WinRT class:

#pragma once

 

#include <unordered_map>

#include <collection.h>

 

using namespace Windows::Foundation;

using namespace Windows::Foundation::Collections;

 

namespace SomeComponent

{

    public ref class SomeRTClass sealed

    {

    public:

        SomeRTClass()

            : someStr_(L"")

            , someInts_(ref new Platform::Vector<int>())

        {

            // Do nothing

        }

        ~SomeRTClass() { }

 

        property Platform::String^ SomeStr

        {

            Platform::String^ get() { return someStr_;}

            void set(Platform::String^ value) { someStr_ = value; }

        }

 

        int GetKeyedNamesCount(void) { return m_keyedNames.size(); }

        Platform::String^ GetKeyedName(int key)

        {

            try

            {

                return ref new Platform::String(m_keyedNames.at(key).data());

            }

            catch(...)

            {

                throw ref new Platform::FailureException();

            }

        }

 

        void SetKeyedName(int key, Platform::String^ value)

        {

            m_keyedNames[key] = std::wstring(value->Data());

        }

 

        property IVector<int>^               SomeInts

        {

            IVector<int>^ get() { return someInts_; }

        }

 

    private:

        Platform::String^                    someStr_;

        Platform::Vector<int>^               someInts_;

        std::unordered_map<int,std::wstring> m_keyedNames;

    };

}

Anything in your component's public interface needs to deal in WinRT types (including fundamental types such as int; see: http://msdn.microsoft.com/en-us/library/windows/apps/br212455(v=vs.110).aspx ).

Public collection types must be WinRT interfaces to collection types (i.e. IVector<T> instead of Vector<T>).

Private code can use non-WinRT types such as std::unordered_map.

Also, the sealed keyword is only necessary to use the WinRT component in JavaScript.

If you ever did any managed C++ coding, you will likely notice that C++/CX syntax is pretty much the exact same syntax as managed C++. Microsoft elected to reuse the syntax since it had already been approved as a language extension by the ECMA standards organization. But C++/CX is entirely native; .NET is not involved and there is no GC running in the background (WinRT classes are automatically reference counted, remember).

For more on C++/CX and WinRT (including all of the rules governing WinRT components), I recommend checking out http://dev.windows.com/ (especially the Visual C++ reference for Windows Runtime page - http://msdn.microsoft.com/en-us/library/windows/apps/br229567.aspx ).

Visual Studio and C++

Initial configuration

If you're using VC++ 2010 Express for the first time, there are a few settings changes I recommend making (especially if you are coming from C#).

First, in the "Tools" menu under "Settings" switch to "Expert Settings". I recommend this for all Express SKUs of Visual Studio.

Next, in "Tools"->"Options…" under "Environment"->"Keyboard" switch the drop down menu from "(Default)" to "Visual C# 2005". This will prevent you from going crazy when F6 doesn't compile. If you are more comfortable with a different key mapping, use that one instead. The point is to switch to keys that you are familiar with.

While in "Options…" change any other settings you like. One thing I like to do is under "Text Editor"->"C/C++", in "General" I like to turn line numbers on and in "Tabs" I've taken to setting "Insert spaces" rather than "Keep tabs".

IntelliSense

If you’re using almost any of the Visual Studio keyboard mappings, typing Ctrl+J will bring up IntelliSense. In VS11 IntelliSense should appear automatically in C++. In VS 2010 and earlier, you need to manually invoke it.

Code snippets

I’ve never made too much use of code snippets, though I find myself using them more and more since I learned that the magic secret to accepting the parameters and starting to code is just to hit Enter.

Code snippets are a new feature for C++ in VS11; they don’t exist in earlier versions. If you’ve never used them (in any language), in a C# project start typing ‘for’ to begin a for loop but once IntelliSense has chosen the for snippet, press the Tab key twice and watch as a for loop appears complete with automatic fields that you can edit (use the Tab key to switch between fields). When you’re done editing the fields, press Enter and the cursor will be transported within the loop body with the field edits you made (if any) accepted and appearing now as normal text.

Including libraries

In C++, it's usually not enough to just include a header file. Normally you need to tell the linker to link against a library that implements the code that is declared in the header file. To do this, you need to edit the project's properties, accessible as "ProjectName Properties…" in the "Project" menu. In the properties, under "Configuration Properties" -> "Linker" -> "Input", one of the fields is "Additional Dependencies". This is a semi-colon separated list of the .LIB files you need to link against. It should end with

%(AdditionalDependencies)

so that any additional libraries that are linked via MSBuild are properly added. For a typical DirectX 11 Metro style game you might see the following:

d2d1.lib; d3d11.lib; dxgi.lib; ole32.lib; windowscodecs.lib; dwrite.lib; xaudio2.lib; xinput.lib; mfcore.lib; mfplat.lib; mfreadwrite.lib; mfuuid.lib; %(AdditionalDependencies)

Precompiled headers

A precompiled header (PCH) is a special type of header file. Like a normal header file, you can stick both include statements and code definitions in it. What it does differently is that it helps to speed up compile times. The PCH will be compiled the first time you build your program. From then on, as long as you don't make any changes to the PCH or to anything that is #included in the PCH, the compiler can reuse its pre-compiled version of the PCH. So don't stick anything in it that is likely to change a lot. But do add things that are unlikely to change. This way your compile times will speed up since a lot of code (e.g. Standard Library headers) will not need to be recompiled every build.

If you use a PCH, you need to #include it at as the first include statement at the top of every CPP file (but not at the top of header files). If you forget to include it or put some other include statement above it then the compiler will generate an error. This is just a result from the way the compiler needs to see PCHs in order to make it work.

Generating assembly code files

If you want to view (a very close approximation of) the assembly code that your code is compiled down into, in your project’s properties, under "Configuration Properties"->"C/C++"->"Output Files" set the "Assembler Output" option to something other than "No Listing".

I’d recommend either "Assembly-Only Listing (/FA)" or "Assembly With Source Code (/FAs)". I normally use the former; it sprinkles enough line number comments that I can cross-reference to see what code I’m dealing with. The latter can be helpful if you want one place to see it all rather than flipping back and forth between whatever you’ve opened the .ASM file in (I use Notepad++) and Visual Studio.

Note that the assembly that is generated uses MASM macros (you can look them up on MSDN). If you don’t know what a particular assembly instruction means (e.g. LEA), you can search the internet for it or try downloading the appropriate programming manual from Intel’s site (assuming x86/Itanium) or AMD’s site (assuming x64) or ARM Holding’s site (assuming ARM). If you’ve never learned any assembly, I definitely recommend it (try just creating a simple Windows Console app). The course I enjoyed most out of all the Comp Sci classes I took in my undergrad minor in CS was where I learned MIPS asm.

Terrifying build errors

Chances are if you come across a build error that looks completely horrible, it’s from the linker. You’ll see messages like this, for instance:

Error  2          error LNK2019: unresolved external symbol "public: __thiscall SomeClass::SomeClass(wchar_t const *)" (??0SomeClass@@QAE@PB_W@Z) referenced in function "void __cdecl DoSomething(void)" (?DoSomething@@YAXXZ)            D:\VS2010Proj\CppSandbox\CppSandbox\CppSandbox.obj CppSandbox

All that’s saying is that it cannot find some function you said it should be able to find. In this case, I added the ‘inline’ keyword to a constructor function definition that was in the CPP file without remembering to relocate that definition to the header file. Any inline functions need to be in the header so that the linker won’t hate you.

All those ?? and @@and weird letters are just the way that C++ mangles names when it has compiled code into object files. Name mangling is internally consistent for the compiler in question but the ISO/IEC standard doesn’t mandate any particular schema for name mangling such that different compilers can (and often will) mangle things differently.

Anyway, normally if you see some sort of horrifying build error message, chances are good that it’s from the linker and that it’s an unresolved symbol error. If so, if it’s saying it can’t find something that you wrote (in the above case my SomeClass::SomeClass(wchar_t const *) constructor function (I always write ‘const type’ not ‘type const’ so even that bit is reconstructed)) then check to make sure that your declaration (in the header file) matches the definition (usually in the code file but maybe you put it in the header or maybe you forgot to write it or maybe you declared it inline but still have it in the code file). If it’s someone else’s function (or other symbol), then chances are that you didn’t tell the linker about the .lib file that contains it.

In .NET you just add a reference to an assembly and you get both the declaration bits and the actual definition stuff all in one. In C++, the declaration is the header file while the definition stuff (excluding inline stuff, which needs to be in the header file too) is in a separate library. See above about including libraries. Search the MSDN library for the symbol that it’s telling you it is missing and see if you can find the name of the library file you need to add.

C++ build errors can look pretty scary. Especially when you get a build error involving a template… those can make you want to quit. But don’t. Never let the horrible error messages win.

First figure out if it’s coming from the compiler (it’ll have a C#### error number format) or the linker (LNK#### error number format).

The compiler usually means some sort of syntax error. Check to see things like whether you forgot the #pragma once at the top of your header file. Another problem could be where you are using something from the standard library (e.g. ‘endl’) but forgot to have either a #using namespace std; or else to prefix it with std:: (i.e. ‘std::endl’). You can do either (or both) but must do at least one. And some things might be in a different namespace (in VS 2010, some functionality is in the stdext namespace, for example). The same goes for any namespaces you might be using in your own code.

If you aren’t having any luck on your own, try going on MSDN and typing in the first part of the error message. Chances are good that you’ll get some helpful links to discussions on the MSDN forums, on StackOverflow, perhaps an MSDN article or an MSDN blog post, … maybe even just the error code’s page itself will have the hint you need. If all else fails, post a question on a forums site (MSDN, the appropriate StackExchange site, the App Hub).

A linker error is typically an unresolved symbol, which usually means you either have a mismatch in declaration and definition, have an inline outside of its header, or else don’t have the right library added to the project’s extra dependencies in the project’s linker options. If it’s something else, try the strategies from the previous paragraph; they apply just as well to linker errors as to compiler errors.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Thursday, February 02, 2012 8:45 AM | Feedback (4)
Monday, January 30, 2012
DMARC – A new anti-spam effort that looks promising

While doing my usual rounds of reading the news I came across an interesting post in the New York Times Bits blog: http://bits.blogs.nytimes.com/2012/01/30/technology-companies-pair-up-to-confront-the-scourge-of-internet/ .

It seems that most of the big players in the internet mail world (Microsoft, Google, Yahoo, Facebook, AOL, LinkedIn, PayPal, and more) have been working together in an attempt to formulate a new way of better identifying not-spam (and thereby more easily identifying spam) by using existing technologies in a consistent way. The group has come up with DMARC (Domain-based Message Authentication, Reporting & Conformance), “a technical specification […] to help reduce the potential for email-based abuse by solving a couple of long-standing operational, deployment, and reporting issues related to email authentication protocols.” (See: http://dmarc.org/index.html ).

Ultimately the goal is to package it up and submit it to the IETF for consideration to become an RFC (i.e. an internet standard). I do very little mailing from my own domains currently but that may change in the future. It is nice that there is now a way that I can potentially show that I am me; the fear of winding up in spam folders is part of the reason why I have not used my domains for many email activities. I’ve glanced through it, but I need to do more research before I can figure out whether this is something I can do directly or if it’s something I need to talk to my hosting company about. Either way, it’s definitely something on my to-do list and is something that all small developers should have a look at as a way of facilitating communication with opt-in customers and with prospective customers, clients, and business partners who send you email.

--------

On an unrelated note, I’m making good progress on my next post in the XNA to DirectX series. It’s already coming in at over 4100 words and I expect it to grow a fair bit longer still. The reason for the length is that it’s a post about modern C++ for C# programmers who either haven’t used C++ ever or haven’t used it for several years at any rate. C++11, the latest standard, is a huge improvement over the previous C++03 standard and really makes C++ a very different language than what it was a decade ago. I had initially been planning out a whole series on it (and even had two posts well along the road to completion) but I decided that it was more feasible and practical for me to create a brief guide of key topics. (The prospect that Shawn Hargreaves may be writing about C++ soon did factor into that decision; he undoubtedly knows more about the topic than I do, especially when it comes to writing games and game engines, so I’m looking forward to his posts as and when they come.)

I want to have something covering key C++ topics in order to set a baseline of knowledge and so that’s what I’m working on. Once that’s done, I’ll know that I can dive into DirectX technologies without needing to worry about writing up ad hoc explanations of the C++ constructs in each bit of code. I’ll also have a central place where I can add new topics and tweak existing topics whenever the need arises. So keep an eye out for that post (hopefully within the next few days). After that we dive into DirectX, likely starting with basic D3D11, with coverage on various other technologies (XAudio2 and Media Foundation, XInput, D2D, DirectWrite, DirectXMath, etc.) in subsequent posts. I’m considering writing with the goal of creating the components needed for a good, basic framework for 2D games (perhaps loosely patterned on XNA’s Game State Management sample, though I haven’t had the opportunity to prototype that yet to see whether it would make sense). We’ll see. For now I need to finish up the C++ post.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Monday, January 30, 2012 3:45 PM | Feedback (1)
Saturday, December 31, 2011
Getting started with Metro style DirectX

A little more than three months ago, Microsoft hosted the //build/ conference at which they unveiled the upcoming version of Windows (commonly called Windows 8, though I don’t know if the marketing folks have accepted the fact that that is the name most of us are expecting for it yet). They released to the developer world a build of it called the Windows Developer Preview (and Windows Server Developer Preview) along with various tools for creating the new “Metro style” apps. I wasn’t able to make it to //build/ but I’ve watched a lot of the sessions in the past few months (53h43m04s and counting) and I’ve been running the developer preview a lot both on a developer machine and on a Samsung Series 7 Slate that I bought for testing and development.

So far I’m very impressed. As far as UI, there are some small changes I’d like to see. I wish the mouse would work more like touch input; having mouse and touch be different isn’t intuitive (for me) and the touch scheme has a very well-designed flow so I really don’t think it makes sense to keep the mouse in a bizarro legacy interaction style (scroll bars were always a kludge and the metro system bar should be on the right for all input interfaces in my opinion; let people who want the current Metro mouse style select it as a legacy option in Control Panel or at least give those of us who want the mouse to work like touch the option to enable that in Control Panel). But it’s a “developer preview” (i.e. pre-Beta) so such things may change in the beta (expected in late February) and/or in subsequent pre-RTM releases.

I really like the new Metro programming model (with one exception*). And since that’s what this post is about, let me explain it a bit. I want to clear up some misconceptions to begin with.

First, Metro style apps share some design elements (e.g. active tiles rather than dead icons) with Windows Phone but are an evolution from Windows Phone and differ in certain areas, sometimes significantly. If you think it’s all just colored boxes and black backgrounds, then I encourage you to watch Sam Moreau’s talk, Designing Metro style: principles and personality (and also to revisit Windows Phone since it’s evolved quite a bit from its RTM release). I am by no means a designer, but I found it fascinating. I also highly recommend watching Jensen Harris’ talk, 8 traits of great Metro style apps.

Second, Metro style apps don’t replace .NET (or Win32 or Web Applications). You can continue writing .NET apps (including XNA games) and expect them to run without any compatibility problems in Windows 8 Desktop style. Right now it’s not clear whether Desktop style apps will be supported on ARM-based tablets, but if you’re looking to create tablet apps, you really should be using Metro style, not Desktop style, since design of the Windows Runtime (more about that shortly) makes creating touch-friendly apps really easy. If you do any XAML development (WPF, Silverlight) then your XAML skills and even much of your XAML markup will translate directly into the world of Metro style apps. Much of your .NET code will translate directly as well, though there are some differences (and if you’re looking to create WinRT components that can be used in other languages/runtimes then there are some significant differences in order to meet ABI-compatibility requirements that will allow your component to be projected into those other languages in a way that meets the expectations of developers who use those languages. One thing you’ll notice is that .NET 4.5 maintains the same 4.0.30319 version number as .NET 4.0. This is intentional, not an oversight. .NET 4.5 is a superset of .NET 4.0 and the .NET teams at Microsoft have spent a lot of time and effort to make it so that existing .NET 4.0 apps can take advantage of the (in some places huge) performance increases in .NET 4.5 without any changes. There are new APIs (including new APIs for WPF) but backwards compatibility was one of the design goals so you should expect your existing Desktop apps to just work. If you’ve looked at anything about Metro, you’ve undoubtedly seen the (infamous) chart which was designed to highlight aspects of the Windows Runtime and wound up confusing people into thinking that Microsoft lost its mind and threw away decades of work and compatibility. Remember that Microsoft is a company that has built its reputation on backwards compatibility (to the point where they’re still maintaining bug-level compatibility for old 16-bit Windows 3.1 and earlier APIs (with due consideration given to security issues, of course) in order to let companies continue using applications they rely on in the latest versions of Windows.

Ok, so that gets us to Metro style and the Windows Runtime (“WinRT”). Metro style apps use the Windows Runtime (and a small number of Win32 APIs (mostly DirectX)) as their interface to the OS. The Windows Runtime is projected into various languages in ways that are natural and familiar for their developers. So there’s the WinJS library that exposes WinRT as a collection of JavaScript objects (all found within the Windows object, thereby mimicking namespaces) and even does things like project event handlers using both the on_______ function syntax as well as the addEventListener and removeEventListener functions (allowing multi-cast delegates) and adjust the casing of method names to match the conventional JavaScript function syntax where only objects that can be newed start with a capital letter while methods (functions) of objects use camel casing with the initial letter being lower case. Similarly it projects into C++ via the C++/CX syntax (C++ Component Extensions) which looks like C++/CLI but is entirely native rather than .NET (C++ developers can also use WRL to bypass C++/CX if they want to, but it’s not pretty and so most WRL stuff is there really just the implementers C++/CX itself with exceptions like ComPtr that you’ll find used in DirectX programming). Lastly, WinRT is projected into .NET using a combination of BCL classes (e.g. System.String is a projection of WinRT’s HSTRING type) along with the new Windows.* namespaces.

The takeaway from the above is that WinRT is an OS interface (under the hood it’s design is based on COM with a lot of improvements and advances), just like .NET and Win32. It’s projected into different languages in ways that are natural for that language. Where it makes sense, those projections are done via existing things such as .NET classes. But it doesn’t eliminate the Desktop style version of those models. Just provides a new, clean, modern OS interface that will likely supplant Win32 and .NET within the next 10-15 years for most use cases.

Which gets us to Metro style presentation layers. As of the developer preview, your Microsoft provided options are:

  • HTML5/CSS3 with JavaScript;
  • XAML with C#/VB/C++ (native, not the .NET CLI version); or
  • Raw Direct3D (including Direct2D and DirectWrite) with C++.

For high performance game development, Microsoft recommends using Direct3D (and other DirectX APIs) with C++. This gets me to my * above. They haven’t announced a new version of XNA for Metro style apps and the existing XNA, being based on DirectX 9, can’t be used for Metro style apps. This has been a difficult thing to come to terms with. XNA completely changed my life. I’m a better, happier person than I was before I found it. XNA is still the way to go for XBLIG and Windows Phone game development. And you can continue using it to create Desktop style games (it’ll run just like it was Windows 7). But I’m quite sad that they haven’t announced a Metro style version of XNA, though it would certainly be a massive undertaking due to the sea change between DirectX 9 and DirectX 10 (continued in DirectX 11). For those looking for .NET solutions that’ll work in Metro style apps, have a look at SharpDX, (possibly) SlimDX (I believe a Metro-style port is in the works but am not sure), and (possibly) projects like ANX.Framework (not currently targeting Metro style but may in the future).

---------

And thus we arrive at getting started with Metro style DirectX. I’m really excited about the new Windows and about Metro style and the Windows Runtime. I’ve been learning DirectX programming for a while, but it’s taken on a new urgency so the last few months have been a bit of an unexpected cram course for me. But I do believe that I grok it now (or much of it anyway). And I’ve decided to help those of you who are, like myself, XNA/.NET developers who have decided to take the plunge into the world of Metro DX with C++.

Some good news first. If the last time you looked at C++ was around the turn of the millennium, it has become much better. The C++11 (formerly called C++0x) additions make it a much nicer language and the new Windows Runtime stuff that replaces the old C-style Win32 core APIs (no more WndProc and other dark incantations; it’s real objects with events and everything now) is a huge improvement. The improvements to C++ IntelliSense in VS11 are huge and Visual C++ now supports code snippets and other productivity features.

None of this changes the fact that it’s still C++ though. It still has separate header files and code files which makes for a lot of minor annoyances. It still requires you to tell it which libraries to link against (which you do by viewing the project’s properties and then under “Configuration Properties” in “Linking” under “Input” adding them to the “Additional Dependencies” property) and throws compilation hissy fits with horrifying error messages if you make some minor mistake like try to call a static method via, e.g., ThreadPoolTimer.CreatePeriodicTimer(…) rather than ThreadPoolTimer::CreatePeriodicTimer(…) (a thousand apologies oh great compiler for daring to offend you with syntax that you clearly understand but nonetheless consider an abomination). (Yes, me and C++ have a long, at times ugly, history, but with age I’ve learned to mostly just accept it for what it is rather than pointlessly cast aspersions upon it.) Personally, I’d say that I’m now about 75% as efficient in C++ as I am in C# and I don’t really expect that to ever improve since C++ is just more verbose and demanding than C# is and improving it would require changes that would break the language and cause its diehard fans to rise up with torches and pitchforks.

This isn’t a one-off post. I’m planning a series of articles to help relate DirectX 11 to XNA and the C++ Standard Library to the .NET Framework. I can’t commit to a particular schedule but I’m hoping for a cadence of approximately a post a week.

Though I still haven’t actually told you how to get started so I can’t quite wrap up this post. You need a copy of the Windows Developer Preview and VS11 Express for Windows Metro style or VS11 Ultimate. The preview versions of VS11 won’t install on earlier versions of Windows. Note that installing the Windows Developer Preview is a one-way operation; you have to pave and reinstall if you want to go back to Windows 7/Vista/XP. I bought a separate hard drive and installed it to that. Others have used Virtual Machines. Search around; there’s a lot of good advice. For the developer tools version of WDP, you’ll need either a dual layer DVD+/-R or a thumb drive that is at least 8 GB.

Once you have everything installed, you’re ready to begin. I recommend reading Chuck Walbourn’s Getting Started with Direct3D 11 and the materials he links to. I especially recommend reading “Introduction to Direct3D 10” (SIGGRAPH 2007) since Direct3D 11 builds on the huge changes that were introduced in Direct3D 10. One of those changes was to scrap the old caps (capabilities) system that D3D 9 used and replace it with a bucketing system that is now known as feature levels. D3D10 hardware has to implement almost the entire spec (there are only 2-3 things that are optional); the same is true for D3D11 hardware and the D3D11 spec (which is, itself, a superset of D3D10, which is a superset of the capabilities in D3D9). The feature levels allow you to use D3D11 to target most D3D9 GPUs in code (along with D3D10 and 11 GPUs, of course). Rather than build a completely separate rendering pipeline for older cards, you can now just build one base rendering pipeline that works for all hardware and add in more advanced features (like geometry shaders and tessellation) to your graphics pipeline based on the feature level you get back when creating the device along with some performance checks to account for different hardware levels. (An entry level DX11 card may implement all the same things as a high end DX11 card, but it has less ALUs, fewer shader units, a lower clock speed, and slower RAM, all of which combine to produce a distinct difference in performance (and power usage, which is important for laptops and tablets)). The other big change in D3D10 was to change how resources (e.g. textures and vertex buffers) are created such that they are now validated at creation time rather than every time they are bound to the pipeline (as in D3D9). This creates a big performance gain.

The big change in Direct3D 11 was the separation of the graphics device into a device and one (or more) device contexts in order to make multithreading much better. A game will still have one ID3D11Device which is used for things like resource creation (including shaders) but it now will have one ID3D11DeviceContext which serves as the immediate context (i.e. it renders to the back buffer) and zero or more device contexts which are deferred contexts (they render to a command list that the immediate context can then take and execute exceedingly fast). On multicore machines, it can make sense to split off certain rendering operations onto a separate thread in order to perform the CPU side of rendering in parallel (one example being a particle system).

The big change in Metro style DirectX is that D3DX is gone. Desktop apps can still make use of it, but Metro style apps need to use other APIs (e.g. the D3DCompiler_xx.DLL APIs - http://blogs.msdn.com/b/chuckw/archive/2010/04/22/what-s-up-with-d3dcompiler-xx-dll.aspx).

One of the best ways to learn DirectX is with code samples. The samples provided for the Windows Developer Preview are all pretty good and this explanation of the Marble Maze sample does a particularly good job of explaining how a simple 3D game comes together. Much of the code can easily be reused with little-to-no modification for your own games. There’s code that simplifies loading everything from textures to audio to 3D models. I also strongly recommend the //build/ videos about DirectX. They demonstrate a lot of the really neat features that have been added to DirectX and to Visual Studio (PIX is now integrated into Visual Studio, for instance, and you can now do code analysis for C++ (even in the Express version!).

Happy new year to all!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Saturday, December 31, 2011 4:06 AM | Feedback (1)
Tuesday, September 06, 2011
Leveraging MSBuild for Ruthless Productivity

(Warning: This is semi-advanced stuff. It’s not hard, per se, but it involves editing important project files manually, which, if done wrong, can render them useless making it so that your code won’t compile (and may not even load into Visual Studio). So back up everything or (better still) commit it to your source control repository before doing anything so that in case you mess something up, you can easily recover! You have been warned.)

I’ve been steadily becoming more familiar with MSBuild over the past weeks and months. As my familiarity has grown, so too has my conviction grown firm that MSBuild is the unsung hero of the programming world.

MSBuild, also known as the Microsoft Build Engine, is a program that parses XML files and executes various commands (known as “Tasks” ) contained within them based on the target ( “Targets” ) or targets that are specified. You’ve undoubtedly looked through your project directories over the years and seen files with extensions like .csproj , .vbproj , .vcxproj , .fsproj , and so on. You may even have opened one up in a text editor before and seen a whole large jumble of XML tags with names like <PropertyGroup> and <ItemGroup>. These files are your project files; they’re what tells Visual Studio what files are part of your project, what assembly references your project depends on, and so forth. They also, in part, define what happens when you choose to build your project or solution via the Build menu or via a shortcut key such as F6.

(n.b. Native C++ projects, i.e. .vcxproj files, have their own targets defined in its own special MSBuild files. The rest of this is going to be discussing managed projects, so while it may make interesting reading, remember that Native C++ does its own thing, with its own properties, item groups, and targets that are designed for dealing with the target platform-specific nature of native code).

One thing that’s important to understand is that simply looking at a .csproj (or other .*proj) file will not tell you what is going on. The reason for that is the <Import> tag, which is used to import various other files. One file that’s imported in almost all projects is Microsoft.Common.targets. This file is quite long and consists of more MSBuild XML. What’s important about it is that this is where the default build pipeline is set forth. It defines a number of targets, chief among them being Build, BeforeBuild, CoreBuild, and AfterBuild. It also sets the <Project> tag’s DefaultTargets parameter to be the Build target.

Build itself calls the BeforeBuild, CoreBuild, and AfterBuild targets in that order. CoreBuild is what does all the reference locating, compiling, and linking stuff. It has a number of targets that it runs, but we aren’t going to concern ourselves with that other than to say that the PreBuildEvent and PostBuildEvent targets run within CoreBuild at appropriate times. If you’ve ever viewed your project’s “Properties” in Visual Studio, you may have noticed the “Build Events” tab in which you can specify command line commands to run pre-build and post-build. That’s how these are hooked up, so know that the BeforeBuild target runs before PreBuildEvent and that PostBuildEvent runs before AfterBuild.

Well, so far this has been a dry walkthrough of arcane XML. Where’s the “ruthless productivity” part? It has arrived. We simply needed the dry walkthrough to get to it (and understand it, more importantly). When you build a project, it runs the Build target because that’s what the project (via importing Microsoft.Common.targets) has been setup to do. By default the BeforeBuild and AfterBuild targets do nothing. You, however, can change that. If you edit your .csproj or .vbproj file (Visual Studio’s XML editor works great, but note that the project needs to be closed before you can edit its project file), you’ll find that you can either uncomment the existing, commented out BeforeBuild and AfterBuild targets or else (if they aren’t there or if you feel like making your own tags instead) you can write your own. Do you have anything that you need to do before you build a project? Perhaps for an XNA game you want to copy the latest art assets out of some other directory and move them to the content directory so that your game builds the latest assets. Perhaps you have some files that need to run through a tool or maybe after the build finished you want to copy the new build to a network drive so that you (and other members of your team) can access and run the latest build.

This is where MSBuild shines. Simply open up your .csproj or .vbproj file (or even a .contentproj file) and add some tasks to the BeforeBuild and/or AfterBuild targets. There are many predefined tasks to choose from and, if none fit your needs, you can always write your own custom task. When MSBuild runs a project file, the working directory is generally the directory in which that project file is located; this is handy for when you’re running a Copy task since you can use relative paths (rather than hard-coded ones) so that someone else on a different machine with a different directory structure can still build the project correctly. If you want to run some program, you can make use of the Exec task. You can even check various conditions and abort the build with an Error task if a check fails.

So where does this leave us? Now, rather than have to manually perform various tasks that are necessary to your build process or that you want to perform after the build, you can instead automate them with a few simple lines of XML. Even complex tasks are not outside the read of MSBuild; you just may need to write a custom task for it or perhaps run several different tasks back-to-back (with some error checking thrown in for good measure, of course).

Some final notes. I didn’t really talk much about the ItemGroup and PropertyGroup tags. These are container tags into which you can add various tags with your own unique names. An ItemGroup is normally used to specify one or more files whereas a PropertyGroup is normally used to specify and store values and for evaluating conditions.

A member of an ItemGroup is normally dereferenced via the @(SomeItemTag) syntax, which will by default produce a semicolon separated list of things that are specified in tags in the project’s ItemGroup(s). The above would pull out all items within an ItemGroup that were stored inside <SomeItemTag Include=”text here”></SomeItemTag> pairs. Note that all items must have an Include attribute and that multiple elements within the same Include attribute should be separated with a semicolon. With ItemGroups, you can have the same tag multiple times (and within multiple ItemGroup tag pairs) and it will concatenate them all (provided that you properly escape any special characters using %xx syntax, where xx is the hex code of the ASCII value of the special character ).

Members of a PropertyGroup on the other hand are dereferenced via the $(SomeProperty) syntax. Unlike with ItemGroup, you can only have one instance of a specific tag for PropertyGroup. To the extent that you use the same tag multiple times, only the value of the last instance of the tag will be used. Properties don’t require an Include attribute and normally are specified by including the value within a tag.

As a brief example, here’s a simple MSBuild file that shows some usage of a target, a task type (the Message task), and various ItemGroup and PropertyGroup groups.

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Hello" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Hello">
    <Message Importance="high" Text="@(SomeItemTag)" />
    <Message Importance="high" Text="$(SomeProperty), $(SomeOtherProperty)" />
  </Target>

  <PropertyGroup>
    <HelloWorld>Hello world</HelloWorld>
    <SomeProperty>$(HelloWorld)</SomeProperty>
  </PropertyGroup>
  <PropertyGroup>
    <SomeOtherProperty>how's it going</SomeOtherProperty>
  </PropertyGroup>
  <ItemGroup>
    <VariousFileNames Include="Shiver.bmp;Me.tif;Timbers.xcf"></VariousFileNames>
    <SomeItemTag Include="Ahoy.png;Arg.jpg;@(VariousFileNames)"></SomeItemTag>
  </ItemGroup>
  <ItemGroup>
    <SomeItemTag Include="*.msbuild"></SomeItemTag>
  </ItemGroup>
</Project>

 

If you run a Visual Studio Command Prompt (to setup the environment variables and paths), you can save this to a text file named, e.g. “test.msbuild” and then run it from the command line via:

msbuild test.msbuild

The file name extension doesn’t matter, btw. I used it just for easy knowledge of the file’s contents. Another thing to know is that MSBuild predefines a large number of properties. If you want to see what all they are, do the same as above only this time run it as:

msbuild /v:diag test.msbuild

That tells msbuild to use a verbosity of diagnostic. To find out other command line parameters, just type:

msbuild /?

and it will show you. You can do things like specify properties (and their values) and set a different target than the DefaultTargets target. Say we added a target above called “Goodbye”. Just running MSBuild as is would run the Hello target (and only the Hello target). If you instead used the command line switch, you could tell it to run the Goodbye target or even both targets (in whichever order you specify).

This only scratches the surface of what MSBuild can do. I left out quite a bit that the links do a good job of explaining, so make sure to read them. If you find this post interesting, you might want to bookmark it. I wrote it in part so that I would have something to refer back to whenever I needed, It’s not the kind of thing you’re likely to use every single day or even every week. You might only modify your .csproj file once or twice in the course of an entire project development cycle. So it’s easy to forget quite a bit of this as time passes. If you have any questions, leave comments and I’ll respond to the extent that I can. I may return to this topic again in the future, but for now this should be a good, quick intro to MSBuild.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Tuesday, September 06, 2011 8:26 AM | Feedback (0)
Friday, August 26, 2011
SmartAssembly 6.1 Review

It’s been quite a while since I’ve done a GeeksWithBlogs.net Influencers review. This time, I had the opportunity to check out Red Gate’s SmartAssembly 6.1, which is a integrated collection of tools for modifying and manipulating assemblies. Now that phrase, while accurate, is quite a mouthful. So what all does it actually do?

SmartAssembly has the ability to:

  1. Do strong name signing;
  2. Add automated error reporting;
  3. Add feature usage reporting;
  4. Merge dependencies (e.g. libraries) into the main assembly (which lets you then apply obfuscation, etc., to them as well);
  5. Embed dependencies into the main assembly (letting you compress and encrypt them in the process, making deployment faster and maintenance nicer);
  6. Automatically prune unneeded metadata like the names of events, properties, and methods (making the assembly smaller such that it’ll run faster and also be much harder to understand if decompiled);
  7. Obfuscate the names of classes, methods (including properties), and fields, with varying levels of configurability;
  8. Obfuscate control flow (modifying the order that code runs in (without messing up how it works) such that the logic becomes very hard to understand;
  9. Have a proxy created at runtime for accessing methods, properties, and fields in external assemblies, which makes any attempts to modify the assembly render it non-working;
  10. Compress and encrypt resources;
  11. Encode non-constant strings, which is useful if you need to store sensitive information such as passwords, SQL queries, etc., in your code;
  12. Apply several other protections and optimizations (e.g. sealing classes that aren’t inherited from);
  13. Generate debugging information which will let you debug your modified assembly in your IDE; and
  14. Integrate into your build process.

Which of these you can use depends on the type of assembly you’re working with; various features aren’t available due to technology limitations, e.g. the automated error reporting and feature usage aren’t available on Xbox 360 XNA games since there’s no external internet access. For a list of feature compatibility, go to the Release notes - version 6.xx and scroll down to “Known limitations”, which includes a helpful chart of what is available in what.

Well, the first thing I expect many people will notice is that it does obfuscation. But I don’t want to talk about that first, since SmartAssembly does a lot of other really neat stuff that probably gets overlooked. One thing I found really interesting was the Automated Error Reporting functionality. You just check a box and it automatically adds a wrapper for unhandled exceptions that lets your users send in anonymous error reports either to the free service that Red Gate operates or, if you have SmartAssembly Pro, to your own server using the web service software they provide: Setting up a custom web server for reporting . The thing I really liked about it is that it works with Windows Phone 7 (both Silverlight and XNA), which is my primary development target these days. You get a full stack trace, including the values of various variables (try saying that five times fast :) ), along with a lot of in-depth information, such as the version of the app, the OS (including version), the CLR version, and a hash of the UserHostAddress (which should help you to sort out which reports come from which users). You can set flags on them, save the reports for browsing later, and mark your progress. This is an example of a saved report:

SmartAssemblyExceptionReport

As you can see, it provides a lot of helpful information, including the exception message (in my case, the fact that I haven’t implemented the “Open” button yet, which is something I knew). The other thing Automated Error Reporting will do is try to recover from the exception if possible. In the case of my unimplemented “Open” button, it popped up the little notification message box telling me there was a problem, asking me if I’d like to send details about it in to help improve the software, and then continued on as though I hadn’t pressed the problematic button. This is one of those features that I know I’d normally overlook or pay little attention to, which is why I’m making a big deal about it. The quality of its implementation, the ease of applying it (as simple as just checking a box), and the value that it adds to a .NET application makes SmartAssembly worth its price on this feature alone in my opinion. Have a look at some of the walkthroughs and videos for more information; they’re short and interesting.

On to obfuscation. If you don’t know what obfuscation is, it’s basically the application of various techniques in order to make it very hard if not impossible for someone to take your .NET program and see its source code using a disassembly tool like ildasm.exe or .NET Reflector. I did several tests of its obfuscation capabilities based on projects I’ve completed, that I’m actively working on, and that I just use for testing. My experiences were mostly good.

I struggled a bit getting my WP7 Silverlight app to obfuscate properly and still work correctly. The obfuscated version was having issues with parsing XAML, which is not surprising given that XAML data binding relies on reflection to work properly and obfuscation messes around with all sorts of things.

It turned out that my problem was event handler methods. Specifically, in various places in my XAML, I was handling events with methods in my code-behind class for the Page that weren’t marked public. For Silverlight projects, SmartAssembly automatically excludes anything marked public from name mangling; anything else gets mangled by default. The solution in this case was to either mark those methods public and let SmartAssembly automatically exclude them, to go and mark them manually (when you put a check next to an assembly in the Obfuscation area, a link called “Exclusions” appears next to it, letting you go in and exclude any namespaces, class names, methods (including custom property getters and setters), and fields that you want from having their names mangled), or to apply custom attributes to them. The last solution is probably the best to go with since once it’s all setup, it’ll just work no matter what you change or refactor in your code.

Once I fixed that issue, almost everything worked. I also had an issue with a third-party control that I was using. I was hoping to be able to merge it and obfuscate it (either name mangling, control flow obfuscation, or both), but it was not meant to be. SmartAssembly recommends against trying to merge third party libraries, suggesting that you embed them instead. Embedding isn’t an option for WP7 though, so I had to modify how I was using the control. Initially I had it as a project within my solution and was including it as a reference as a project. What I did instead was build it as a separate DLL and apply obfuscation to it with a separate SmartAssembly project. I then included a reference to the obfuscated, pre-built DLL and it worked like a charm. Many would consider that a ‘best practice’ way of doing such a thing anyway (seeing as you’re rarely, if ever, going to be changing that third party code so rebuilding it all the time makes no sense), so it was a double benefit in that regard. With that issue resolved, everything worked great.

Next I tested a WP7 XNA app that I’m working on. Once I set up the SmartAssembly project, it worked perfectly the very first time. The error reporting was very simple to integrate and a really pleasant surprise (I created an intentional exception, which you can see in the screen shot above, just to test it). It’s something I will definitely be making use of and something I highly recommend to everyone. Do note that if you setup the automated error reporting to email you for every error report, it will indeed do this. If you publish something and a lot of people get errors in one particular place (which might be very common when doing a beta test, for example), you can expect to get a lot of emails as a result. So I recommend dedicating a special email address for that feature, if you choose to use it, so that you don’t wake up to find your personal inbox chock full of messages. :) (This did not happen to me, but I could easily see it happening by accident, especially for something that you’re just doing a private beta for such that you might not think to use a special email address for it.)

The last thing I tested was my PC XNA sandbox app. I have over half a dozen “sandbox” apps that I use to test out various things in different languages and technologies. I most recently used my PC XNA sandbox app to do some stress testing on SpriteBatch draw calls. So it was already setup to not run particularly well, making it a good measuring platform for how SmartAssembly’s various components affect performance. I modified the project to use a WeakReference to track when GC collections occurred, added in a pointless allocation of 5000 bytes every frame, then used a StreamWriter to write out GC data every time a collection occurred; specifically: the current count of collections, current total game time, the time difference (delta) from the last GC collection, and the average time delta between collections. It was already setup to display the current frame rate. For the SmartAssembly-modified version, I initially set it to use Automated Error Reporting, Obfuscation (Types/Methods Name Mangling set to “I want to obfuscate using only Unicode unprintable characters.” and Fields Name Mangling set to “I want to use standard renaming, so that all the fields in a class have a different name.”), Control Flow Obfuscation, and to seal all classes that are not inherited (under Other Optimizations).

The results? The original Release build (run as a standalone program outside of Visual Studio) and the SmartAssembly-modified version of that Release build ran virtually identically. Both maintained the same frame rate hovering between 34 and 35 fps. I stopped both after they hit a GC count of 21 (I didn’t track any GCs that occurred during the LoadContent phase, just during gameplay). The original Release build hit its 21st GC at 61.950 seconds in with an average delta of 2.950 seconds. The SA version hit its 21st GC at 62.067 seconds in with an average delta of 2.956 seconds. Yep, the SA version actually won (though just barely; it could easily be due to my computer doing stuff in the background). Since the test was to see if it hurt performance, and (with several runs of each just to avoid obvious anomalies) they both ran virtually the same, it seemed clear to me that it didn’t.

Just for kicks, I created another SmartAssembly version, this time with everything enabled except for Generate Debugging Information, Strings Encoding, and Strong Name Signing. I also turned up obfuscation to its maximum levels. I also ran this one several times just to confirm the results weren’t anomalous. This build runs an initial GC much earlier than the other tests (after ~1.7 seconds versus ~2.7 seconds for the previous two builds), but then runs virtually the same as the others. An example run hit its 21st GC at 61.065 seconds in with an average delta of 2.908 seconds. But if you exclude the first collection and average the other 20, you wind up with an average delta of 2.969 seconds. The other builds also showed a slightly early first GC so I’m willing to call them functionally identical. What all these tests told me is that this is a great way to protect my programs without any noticeable performance hits.

The last thing I want to talk about is the ability to automatically integrate a SmartAssembly project into your build pipeline. You can add SmartAssembly in to the MSBuild process or into a ClickOnce deployment. I’ve done this for a couple of projects already and it’s quite easy and very smooth. Some projects (e.g. XNA games) generate extra content that needs to be copied into the output directory (for XNA games, any of your content folders along with their XNB files). You can either configure an MSBuild Copy Task to do that for you (just add it in with the SmartAssembly Task into the AfterBuild target) or you can do it by hand or some other way. So just take note that SmartAssembly (when integrated into MSBuild at least; I haven’t tested ClickOnce) only creates the assembly or assemblies that it is operating on at its destination and that it’s up to you to setup a mechanism for copying any other content files that your assembly depends on.

Just as with ANTS Memory Profiler, I found I really liked SmartAssembly. It’s easy to work with, the help materials and learning videos are really good, and it makes a variety of otherwise complicated tasks very easy to do. There’s a 14-day, fully functional free trial for it, so if you’re on the fence, go check it out and see what you think.

(n.b. While I was finishing up this review, version 6.2 was released. The release notes indicate that the changes are very small and shouldn’t have an impact on anything I discussed above. They do mention the provision of sample error reports, which I think is a great addition since it lets you see what you’ll be getting from error reports without having to spend time creating your own.)

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Friday, August 26, 2011 5:57 PM | Feedback (0)
Saturday, August 06, 2011
Interpolation Sample for XNA

One thing I’ve always enjoyed in Silverlight/WPF are the easing functions ( http://msdn.microsoft.com/en-us/library/ee308751.aspx ). The easing functions are commonly used to provide interesting looking animations via key frame-based interpolation.

XNA has a few, limited bits of interpolation built in (primarily Lerp (i.e. linear interpolation) and SmoothStep (i.e. cubic interpolation)). For a sprite animation project that I’ve since set aside (it’s not dead, but it’s been back-burnered for a while now), I replicated most of the Silverlight/WPF easing function (I never got around to figuring out BounceEase and ElasticEase) so that I could use them in XNA. I decided I’d make them available to all of you to use as well. They’re great for spicing up menus and other animations.

The important part of the sample is the Interpolation.cs/Interpolation.vb file; that contains the static class and the two enums that combine together to provide the interpolation. There are two solutions: Interpolation Sample and Interpolation Visualizer. Sample is a basic demonstration of how to use some of the functionality within an XNA game to do things like animate a sprite’s tint color, scale, and position. Visualizer is a WPF app that lets you see what the different enum values produce (and for a few, what the “formula value” does). The code is dual licensed under the MIT License and the Microsoft Public License. You can get it here: C# - Interpolation_SampleCS.zip VB - Interpolation_SampleVB.zip. The zip files contain both the Interpolation Sample and the Interpolation Visualizer despite the names. Note that the Interpolation Visualizer will need to be built once before you MainWindow.xaml will display properly in the designer due to its use of data binding. Until you build it, it’ll probably tell you that there are errors since it can’t use reflection to find things in an assembly that doesn’t exist yet.

Enjoy!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Saturday, August 06, 2011 3:23 PM | Feedback (0)
Monday, August 01, 2011
Dxt Conversion Content Pipeline Extension Sample

I’ve been slowly creating a new WP7 game over these past few months. In the process, I began experimenting with Dxt compression. It’s a very nice feature, especially on the phone where high DPIs make Dxt’s artifacts less visible. One thing I didn’t like, though, was the way that XNA’s default Texture Processor handles resizing to power of two.

When using Dxt compression with the Reach graphics profile, you need to use textures that are power of two sized (e.g. 32x64). Dxt itself requires that the dimensions be divisible by four (it breaks up your image into 4x4 chunks of data in order to compress it), but it’s easier for graphics cards with limited power (such as on netbooks and mobile devices) to process them when the dimensions are restricted to being a power of two as well.

XNA’s built-in Texture Processor has an option to resize your images to power of two dimensions. Unfortunately, the way it does so is by scaling your image. This can produce both odd stretching effects and also a blurry look to the result even when you compensate for the stretching. So I’ve created a quick Content Pipeline extension that resizes the image by padding it rather than by scaling it. I’m quite satisfied with the result and so I thought I’d share it with all of you to make do with as you see fit. The code is licensed under the terms of the Microsoft Public License. You can also instead use it under the terms of the MIT License (a copy of which is included in the zip file) if that works better for you.

I’ve extended the dual licensing to nearly all of my samples and have updated the ones that are affected to include a copy of both licenses. I learned recently that for some people I know the MIT License is more convenient and I like to be as accommodating as I can. If you fit in to that group, feel free to re-download any samples you are interested in to make sure the MIT License is included (my only known exclusion was for a back-port I did of a code sample that was licensed exclusively under the Ms-PL).

To use the Convert To Dxt Processor, build it, and add a reference to it to your game’s content project. Then set your image files to use the Convert To Dxt Processor. You can do this via Solution Explorer by right-clicking on the image file(s) and choosing “Properties” then changing the Content Processor from “Texture – XNA Framework” to “Convert To Dxt Processor”. If your image was not previously a “power of two” sized image, you will need to use an overload of SpriteBatch.Draw that takes a sourceRectangle parameter and use as a source rectangle something like: “new Rectangle(0, 0, width, height)” where width and height are the original width and height of the image. The sample game that is included shows this in more detail.

Without further ado, the samples:

C#: Dxt_CPE_SampleCS.zip

VB: Dxt_CPE_SampleVB.zip

And just so you can see the difference, a sample screenshot:

DxtCPESampleResults

The left hand column (both rows) is the original image without any Dxt Compression or other adjustment. The middle column is the XNA Framework Texture processor. The right hand column is the custom processor I developed. The top row illustrates the images without any scaling or source rectangles used. The bottom row illustrates the XNA Framework processor’s results with scaling applied to obtain the original size and my custom processor with a source rectangle used to clip the image to its original size.

The text along the bottom shows the resulting XNB size for the Windows version using a Release configuration. The comments in the code explain why the size differences appear here and the different way in which they would manifest themselves in a WP7 build. Note that for Debug configuration the Dxt XNBs will be the same size (32.18 KB) and the original XNB will be 143.93KB. The image in question is 160x230 such that it winds up being a 256x256 XNB with power of two adjustment. So even with jumping from 36800 pixels to 65536 pixels, we still wind up with compression such that the image will only occupy 22.36% of the memory that the non-Dxt image does and we end up with reasonably good savings in storage space (for comparison, the original PNG is 43KB). So definitely consider using Dxt compression for your XNA games (both WP7 and PC/Xbox). The memory savings are quite good without much loss in quality.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Monday, August 01, 2011 10:24 AM | Feedback (2)
Tuesday, May 24, 2011
Welcoming Visual Basic Users to XNA

With the release of the Windows Phone Developer Tools 7.1 Beta, Visual Basic joins C# as a supported development language for XNA. I’ve been busily converting my samples to VB recently. They aren’t all done yet, but quite a few are (only three remain that I plan to convert). Rather than make anyone wait, I’ll share what I’ve completed so far and will add more when I have the remainder finished. Without further ado:

Content Pipeline Extension Sample: VB Source CodeRelated Blog Post

DragAndDropGame: VB Source CodeRelated Blog Post

CheckMemoryAllocationGame: VB Source CodeRelated Blog Post

RenderTarget2D Sample: VB Source CodeRelated Blog Post

Guest Account Sign In Utility: VB Source Code (There is no blog post for this tool; it allows you to get a Guest sign in on the Xbox 360 in order to check that you are properly handling guest accounts when purchasing games.)

 

As always, you can find all sample here: http://www.bobtacoindustries.com/developers/utils/Default.aspx. Except as otherwise specified, all source code is licensed under the terms of the Microsoft Public License (in this case, all of the samples above). Please feel free to ask me any questions here, on Twitter, or on the App Hub forums. I plan to make all future samples available in both languages at the same time. Welcome to XNA!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Tuesday, May 24, 2011 6:30 PM | Feedback (0)
Sunday, May 08, 2011
XNA Custom Content Pipeline Extensions Sample

For the longest time, the Content Pipeline was a magic transmogrification device to me. I would add content to a content project and it would get mystically turned into stuff I would load in my game with ContentManager. A few months ago I decided it was time to put an end to its magical aspects and learn how it worked and how I could put it to work. I thought it would be helpful to share what I learned so I created a sample. This sample has two different custom extensions. The first is a complete custom extension from importer to reader. The second is a processor that plugs in to an existing pipeline route.

It’s important to understand the path that content travels through. The Content Pipeline runs through each item of content and instantiates instances of the appropriate class and runs the appropriate methods for it. Here are the stages:

  1. Importer (Build-time)
  2. Processor (Build-time)
  3. Writer (Built-time)
  4. Reader (Run-time)

The Content Pipeline uses MSBuild (an XML-controlled build process that also builds your XNA game, other C# projects, and every other type of project you can “compile” in Visual Studio). MSBuild looks at the .contentproj file, examines the content items, reads in data about which importer and processor they should use and what parameter values should be set for the processor, and the proceeds to call the appropriate ContentImporter<T> class’s Import method. This reads the data in to the build-time model of the data type.

You will commonly find that Content Pipeline extensions (including all of the built-in ones that XNA provides) use a build-time model of the data which is a different class than the run-time model of the data. For instance, Texture2D is the run-time model of two dimensional texture data. Its build-time counterpart is Texture2DContent. Some data is represented with several build-time models. The Model class (for 3D models), is imported as NodeContent data (by the FBX and X importers) and then transformed by the content processor into ModelContent. NodeContent represents a raw version of the 3D content, with as little transformation as possible. The process of transforming data into something that can be used in-game should be left for the ContentProcessor<TInput,TOutput>. Sometimes this means that you import the data into one data structure (e.g. NodeContent) that fairly closely represents what the data coming in from the file looks like and then transform it into another data structure (e.g. ModelContent and the subclasses like MeshContent, MaterialContent, and all the MaterialContent-derived classes) in the processor(s).

Once the processing is done, the Content Pipeline sends the output of the ContentProcessor to its relevant ContentTypeWriter<T>. There can only ever be one ContentTypeWriter for a type. If you tried to implement a ContentTypeWriter for, e.g., Texture2DContent, you will get an InvalidOperationException since one already exists in the Content Pipeline assemblies. The ContentTypeWriter must do three things to be effective. It must override the GetRuntimeReader method, the GetRuntimeType method, and the Write method. GetRuntimeReader returns the assembly qualified name of the runtime reader and GetRuntimeType returns the assembly qualified name of the runtime type. You can read more about assembly qualified names here, but basically what you need is “MyNamespace.SomeClass, MyAssemblyName”. Commonly you would use a game library to hold the runtime reader and runtime type. By default, the assembly name and the namespace will be the same. So if you had a game library called MyLib and you had classes named GameDataReader and GameData in the root namespace of the library, then GetRuntimeReader would return “MyLib.GameDataReader, MyLib”, and GetRuntimeType would return “MyLib.GameData, MyLib”. ContentManager uses this information to invoke the specified reader when it comes across content of the specified type. The Write method uses a Content Pipeline-supplied ContentWriter (which derives from BinaryWriter, adding XNA-specific Write method overloads and other methods to it) to write out the XNB file. It’s up to you to write out everything you need to write in order to be able to read things in during the game. So for arrays, List<T>s, and other collection types, for instance, you want to write out their Length/Count property first so that you can read that in at runtime and know how many items of that type you must then read in. Anything you can think of a way to read in you can write out, so for the most part the only limitations are your own creativity. However you must make sure that your corresponding reader reads everything in exactly the same way that the writer writes things out otherwise you’ll get anything from data corruption/truncation to exceptions.

As mentioned above, the ContentTypeReader<T> is not a part of the Content Pipeline even though it is a mandatory part of a Content Pipeline extension that includes a custom ContentTypeWriter<T>. Instead it’s part of your game itself or, more commonly, part of a game library that you’ve created for that content type. Indeed, ContentTypeReader<T> is found in the Microsoft.Xna.Framework assembly rather than in one of the Content Pipeline’s assemblies since it must be capable of running on any supported XNA platform, not just on PC. There is no special attribute that needs to be applied to the ContentTypeReader<T>-derived class. ContentTypeWriter<T>’s GetRuntimeReader took care of specifying the class when the XNB file was built. Instead, ContentManager, when it receives a call to the Load<T> method requesting that it load data, will open the file, determine the appropriate reader(s) for the content, and proceed to instantiate instances of those readers and pass the opened file to its Read method(s), which then reads in the content to an instance of the class and returns that instance. That is the end of content’s journey through the Content Pipeline and the ContentManager into your game.

The sample has two Content Pipeline extensions, a game library, and a test game with some content processed by the extensions.

TextListContentPipelineExtension is a full extension, reading in a text file (see TextListContentImporter.cs) into a class (see TextListContent.cs) that contains a List<string>, performing some processing on the data that has been read in depending on the values of the processor parameters that have been added (see TextListContentProcessor.cs), writing it out (see TextListContentWriter.cs and TextListContent.cs), then reading it in during the game using the TextListLib game library project’s TextListReader class (see TextListReader.cs) to read it in to TextListLib’s TextList class (see TextList.cs).

TintTextureContentPipelineExtension is a partial extension. It extends TextureProcessor by overriding its Process method to add some additional manipulation options. Rather that try to recreate TextureContent’s Process method ourselves, we just override it and (when we’re done with our custom processing) turn the resulting data over to TextureProcessor’s Process method. Everything else (import, writing, and run-time reading) is done by the built-in classes and methods that XNA provides for processing texture data for use as Texture2D, etc. The code in this is fully-functional but fragile and easy to upset. While I ended up removing it to keep the project simple and focused, I did make use of Stephen Styrchak’s XNA Content Pipeline Debugging template (which I highly recommend as it allows you to do all sort of handy things like set breakpoints that will actually work in a content pipeline extension build process). It saved me from needing to do a lot of trial and error work for this project. And it’s available in all versions of Visual Studio 2010 (Express and Pro+, alike).

Important notes. To use your Content Pipeline extension projects, you need to add a reference to them to your XNA game’s Content project. Then you need to view the properties of the assets in question and, if necessary, set them to use your importers and processors. If you follow my advice and stick the run-time reader and run-time type into a game library, then you need to add a reference to that game library to your game’s references. As always, the code is heavily commented. If you follow the files in the order they are listed above (and then view Game1.cs in Test Game at the end), it should hopefully illustrate clearly the process of creating both a full and a partial extension. Also, while I only included a Windows test game, the extensions should work equally well with Xbox 360 and Windows Phone 7 projects. The code is licensed under the terms of the Microsoft Public License. You can download it here: Content Pipeline Extension Sample (XNA 4.0).

Important notes

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
Posted On Sunday, May 08, 2011 2:33 AM | Feedback (0)
Bob Taco Industries is an ISV focused on game and app development for Microsoft platforms headed up by Michael B. McLaughlin. Mike is a Microsoft XNA/DirectX MVP, a developer, a writer, a consultant, and a retired lawyer. If you're a developer who is just getting started, consider checking out the BTI website's section for developers for links to code samples and other helpful sites.
Tag Cloud