Why can’t I compile Managed DX code using the MC++ Compiler?

This has become a popular quest recently, so naturally that means it must be time to blog about it..  People have been discovering that simple MDX code just doesn’t seem to compile with the Summer 2004 release of the Managed DX assemblies..  Simple code such as this:

Form1 __gc* pForm = new Form1();
// Create a new device
Device __gc* pDevice = NULL;
PresentParameters __gc* pParams = new PresentParameters();
PresentParameters* pArrayParams __gc[] = {pParams};
// Setup params
pParams->SwapEffect = SwapEffect::Discard;
pParams->Windowed = true;
pDevice = new Device(0, DeviceType::Hardware, pForm, CreateFlags::SoftwareVertexProcessing, pArrayParams);

They’ll see compilation errors such as:

Form1.cpp(24) : error C3635: ‘Microsoft.DirectX.PrivateImplementationDetails::IDirect3DDevice9’: undefined native type used in ‘Microsoft::DirectX::Direct3D::Device’; imported native types must be defined in the importing source code
        did you forget to include a header file?

Which is puzzling to say the least, and even more so because using the Summer 2003 SDK release will work correctly.  The problem lies in how the MC++ compiler generates assemblies with native code in them.  First, it will actually create public variations of the unmanaged components (i.e., IDirect3DDevice9) and stick them in the assembly.  Unfortunately, it places these ‘types’ in whatever namespace the #include for the header file happened to be in, normally the ‘blank’ namespace.  Look at the MDX assemblies from the 2003 release in the object browser and you’ll see what I mean as it is literally cluttered with hundreds of these bogus types.

For the 2004 release, we decided to ‘tidy up’ these references, and move them into a single ‘private’ namespace.  Looking at the MDX assemblies for the 2004 release, you’ll see that all of those unusable ‘types’ are now found in the Microsoft.DirectX.PrivateImplementationDetails namespace.  Much cleaner to look at, much better organized.

However, now when the MC++ compiler tries to *use* these assemblies, for whatever reason it looks for the native types to be declared *within that same namespace*.  You’d have to ask the MC++ team why this is since it seems a little strange to me (i.e., C# and VB.NET work just fine without this information)..  In order to successfully compile the code above using the 2004 release you need to actually *include* the d3d9 header files within the namespace mentioned above.  Something such as:

namespace Microsoft
    namespace DirectX
        namespace PrivateImplementationDetails
            #include <d3d9.h>

Thankfully, the MC++ compiler for the Whidbey timeframe is much improved, and situations like this will soon be a thing of the past.  But in the meantime, this is how you get around the issue people are having trouble with.  (Note that you’d also need to include the <d3dx9.h> file if you’re using the functionality provided there)

Comments (5)

  1. Daniel Bruce says:

    Wow, thanks. I’ll need to try this out. I was very unhappy when I had to go back to the previous version of the SDK.

  2. b.gr says:

    Ok, now that you covered MC++ what about the C++/CLI compiler refresh (the test project compiles just fine with the initial compiler)? E.g. structures in the PrivateImplementationDetails cause a C4527 warning ("[structure name] can never be destroyed – user-defined destructor required") and classes end in error C2535 ("Class::~Class(void): member function already defined or declared in [project file]").

  3. ERROR says:

    time to reinstall DX9b SDK for the 4th time… 🙁

    C:Program FilesMicrosoft Visual Studio .NET 2003Vc7PlatformSDKIncludeObjIdl.h(7422): fatal error C1001: INTERNAL COMPILER ERROR

    (compiler file ‘msc1.cpp’, line 2701)

    Please choose the Technical Support command on the Visual C++

    Help menu, or open the Technical Support help file for more information