I’m working on a project to port a 32-bit application for the x64 platform. The first errors that came up when building for x64 were related to inline ASM code, which is no longer supported in VC++ for x64. VC++ has an inline assembler built within the compiler, so you could write assembly code directly in C++ without the need of an external assembler (such as MASM). However, this works only on x86. For x64 and IA64 this is no longer possible. There are several workaround for this:

  • put the assembly code into a separate file and use MASM for x64
  • use compiler intrinsics, which are functions that basically wrap assembly instructions or sequence of intructions
  • rewrite in C++, use Windows APIs, etc.

One error that I had was related to this assembly code:

   __asm {
      int 3
   }

This was used to generate a breakpoint. This can be easily replaced with compiler intrinsic __debugbreak(), which has an identical effect, except that is available on all platforms.

Other errors I had were due to assembly code used to retrieve the value of the EIP and EBP registers. They were used for walking the stack.

__declspec(naked) DWORD_PTR* GetEip()
{
   __asm {
      pop   eax
      push  eax
      ret
   }
}

__declspec(naked) DWORD_PTR* GetEbp()
{
   __asm {
      mov   eax, ebp
      ret
   }
}

The naked specifier is another thing that is not supported on x64. One way to retrieve the value of these registers that works both with x86 and x64 is using RtlCaptureContext, except that this won’t work on operating system previous to Windows XP. In you don’t care about those operating systems, you could write something like this:

      CONTEXT context;
      RtlCaptureContext(&context);

#ifdef _WIN64
      DWORD_PTR* ebp = (DWORD_PTR*)context.Rsp;
      DWORD_PTR* eip = (DWORD_PTR*)context.Rip;
#else
      DWORD_PTR* ebp = (DWORD_PTR*)context.Ebp;
      DWORD_PTR* eip = (DWORD_PTR*)context.Eip;
#endif

Attention, on x64, register EBP (actually RBP) is no longer used. You should use RSP for getting the stack frame.

However, if you want to build a portable stack walking, use StackWalk64. Despite the 64 suffix, this function works on all platforms (x86, x64, IA64). Here is an article that shows how to walk the stack using StackWalk64.

, , , Hits for this post: 9101 .

If you want to port an existing 32-bit application for the x64 platform (especially since 32-bit processors will soon be history), or if you want to target x64 for a new application, the first step in building for x64 is setting up your solution. In this post I will explain what are the steps in configuring x64 as target platform for your projects. Of course you must have the 64-bit compiler and tools installed to make this possible.

Here is an example of a solution with two VC++ project (a Win32 DLL and a console application).

The VC++ wizards add only Win32 (i.e. x86) as target platform for your projects and for your solution (I believe this will change in the future). You can see this by expanding the platforms combo.

If you open the Configuration Manager window for the solution you can see the available solution platforms, and for each project, the available project platforms (these might not be the same).

The configuration manager allows you to set for each pair of solution configuration and solution platform the platform for each individual project. So in theory you can configure for Debug with Win32 at solution level to have, in my demo solution, DemoProject targeting Win32 and DemoLibrary targeting x64. Of course, in practice you probably want to have all projects targeting Win32 in this case, and for the pair Debug with x64 at solution level, have all projects targeting the x64 platform.

To make this platform available for the solution, expand the Active solution platform combo and select . The New Solution Platform dialog will open and allow you to define a new target platform for the solution. Select x64 and for Copy settings from select Win32.

Then make sure you check the Create new project platforms checkbox. In this case the x64 platform will also be defined for every project included in the solution.

After you do this, the x64 platform will be available in the configuration manager for the solution and the projects, so that you can configure the relationships.

Also, the solution platforms combo from the toolbar now displays both Win32 and x64.

But now let’s say you add a new project to the solution. Let’s call this DemoLibrary2.

Since the project was added after defining x64 as a target for the solution and all the projects, the x64 platform won’t be defined for this project (remember, by default, the VC++ wizards don’t add x64 as target platform). You can see this in the configuration manager, where only Win32 is available for the new project.

To define the x64 target for the new project, use the project platform combo and select (see the image above) to open the New Project Platform dialog. Select x64, as new platform, but make sure the checkbox Create new solution platforms remains unselected. Otherwise you’ll get an error, since the platform is already available at the solution level.

After that, the x64 platform will be available for the new project too, and you can make the appropriate configurations in the Configuration Manager window.

And with that you’re done. All you have to do now is configure the settings for each project, for each configuration and platform.

, , Hits for this post: 7987 .

I this post I will talk about the deployment changes in VC++ 2010. When you deploy an application to another machine you have to install not only the application but all the libraries that it depends on. When you build with VC++, you have dependencies on CRT (C/C++ runtime) and possible on MFC and/or ATL.

Visual Studio 2005 introduced a new deployment model for Windows client applications based on isolated applications and side-by-side assemblies. Assemblies can be either shared (globally registered in the system, installed in the Global Assembly Cache – GAC folder in Windows – and available to all applications) or side-by-side (described with a manifest, distributed with the application and available only to that application).

In Visual C++ 2005, library assemblies (such as MFC, ATL, CRT) have been rebuilt as shared side-by-side assemblies and installed in the native assembly cache, WinSxS folder in Windows. That means they are not globally registered in the system, but are globally available to the applications that specify a dependency with a manifest file.

With VC++ 2005 or 2008 there are several options for deployment:

  • static linking: when you link your application statically against VC++ libraries (CRT, MFC or ATL) the application doesn’t have any dependencies so you don’t have to deploy any other VC++ DLLs to the target machine
  • shared side-by-side assemblies: the VC++ DLLs are deployed in the WinSxS folder; this can be done either with the Visual C++ Redistributable Merge Modules or the Visual C++ Redistributable Package; the application requires a manifest file that describes the dependent DLLs and their version
  • private assemblies: the VC++ DLLs are all installed in the same folder with the application; the application requires a manifest file

When you deploy an application built with Visual Studio 2005 or 2008 a manifest file that describes the dependencies, whether you deployed these VC++ DLLs in the local folder or they where installed in the WinSxS folder. If the manifest is missing you get an error. The next image shows the error received when running an MFC application (called Wordpad2008) build with VC++ 2008 on another machine without a manifest.

Though the purpose of this change was to simplify deployment, the result was probably the opposite. As a result Microsoft changed deployment requirements in Visual C++ 2010. You can now deploy applications without a Fusion or satellite manifest. All you need to do is copy the VC++ dependent DLLs to the application folder and run. The next image shows an MFC application (called Wordpad2010) built with VC++ 2010 running on another machine, without a satellite assembly. No error occurs any more when trying to start the application, because local deployment no longer require a satellite manifest.

With VC++ 2010 there are several options for deployment:

  • static linking: same as earlier
  • central deployment: the VC++ DLLs are deployed in the system32 folder; this is useful for updates, because Windows automatically identifies and updates the DLLs that are deployed here
  • local deployment: the application executable and its dependent DLLs are all installed in the same folder; no manifest file is required.

To find more information about deployment and manifest files I suggest these links:

, , Hits for this post: 17178 .

VC++ Feature Pack that came with Visual Studio 2008 SP1 introduced support for the Office Fluent Ribbon. However, developers had to create ribbons entirely from code, because there was no support in the resource editor for that. Visual Studio 2010 comes with a visual designer for the ribbon.

You can choose whether to use a ribbon or a classical menu and toolbar when you create an application.

By default, the created ribbon has one category (Home) and two panels with several commands.

The ribbon can be opened from the resource editor. There is a new category called Ribbon. By default the ribbon resource is called IDR_RIBBON. The description of the ribbon is kept in an XML file called ribbon.mfcribbon-ms, located in the res folder.

When the ribbon is opened, the toolbar displays controls that can be dragged and drop into the ribbon, including categories, context categories, panels, and a series of controls such as buttons, checkbox, edits, progress bar, slider, etc.

There is support for several styles, Office like and Windows 7. These different styles can be seen in the following image.

The designer provides support for quick testing of the ribbon. On the Ribbon Editor toolbar there is a button called Test Ribbon that opens window with the ribbon. You can quickly see how it will look in the application, however, the commands are not available; clicking on the ribbon commands does not have any effect.

You can add handlers for the ribbon commands just like you do for a menu or a toolbar. In Visual Studio 2010 this can be done with the class wizard.

You can read more about the ribbon designed in MSDN or the VC++ Team’s Blog.

, , Hits for this post: 17278 .

In my previous post I talked about the new build system for VC++ from Visual Studio 2010, which is MSBuild and the support for multi-targetting. In this post I will talk about changes to IntelliSense and browsing.

If you go back to the example I was providing in the first post, with the two identical projects created with Visual Studio 2008 and Visual Studio 2010, a second important thing to notice in the comparison of the two solution is that the infamous .NCB file is no longer present in Visual Studio 2010 solution. Instead there is a new file with extension .SDF. This is not just a renaming of the extension, the entire Intellisense for Visual C++ was redesigned in Visual Studio 2010. This is a SQL Server Database file, possible to be opened even in Visual Studio (if one wants to check its content).

In the previous versions of Visual C++, each time you modified a header, the entire solution was reparsed, in which time it was very hard to use the environment. Moreover, the IntelliSense database file (the .NCB file) never seem to shrink, only increased in size, and it could get corrupted from time to time. In the new version, files are parsed on the background, and the IDE does not read all the files, only the current translation unit (which is a source file and all the headers it includes directly and indirectly). As a result, the operation is much swifter and less error prone.

There is also a new disk folder called iPCH in the new solution. This is the storing location for IntelliSense support files and browsing database files (SDF).

#include auto completion

Part of the new IntelliSense and Browsing experience, the #include keyword supports auto-completion for the header files. That means that after typing #include, the IDE displays a list of available headers, filter by their name as you type. The following image shows this.

Call Hierarchy

This feature enables navigation through the code, showing the calls to and from a selected method, constructor or property. When selecting a call in the hierarchy window it shows the code where the call is made.

Red Squiggles

This is a feature that enables highlighting syntactic and semantic errors with a red squiggle line. Hovering the mouse over the line will show a balloon with the error message. The same error is also listed in the Error List window.

Find All References

In the previous versions, this features displayed only the compiler verified results for a search. If you searched for a function M member of a class C it only returned the references where function M was used in the context of C. The new version allows two types of search: one that is focus on speed, and returns all the matches for a symbol regardless the context (but it’s a narrowed search than the one performed with Find in Files), and one that is focused on accuracy and returns only the compiler verified results (i.e. the ones that match the search context).

Class Wizard

Yet another important change is the famous and acclaimed class wizard from VC6, that was dropped in Visual Studio 2002, and was now brought back in Visual Studio 2010.

If you are (or were) familiar with VC6 you know what the Class Wizard is. In Visual Studio 2010 it features basically the same functionality, except that it is improved with search functionality. You can search for command, messages, virtual functions, members or methods. This is great because might not know the exact name of a message or a function, but searching allows you to quickly get it with only typing part of the name. For those not familiar with VC6 this is a single point to add or remove commands, message handlers, virtual functions, member variables and methods. This was a favorite feature in VC6 for a lot of people and there was a constant pressure on Microsoft to bring it back, so here it is.

All these features are detailed in MSDN and on the VC++ Team blog. I suggest several additional readings:

, , , , Hits for this post: 20972 .

The new version of Visual Studio, called Visual Studio 2010 comes with a series of changes for Visual C++. This includes a new build system, new project system, multi-targeting, new IntelliSense, support in MFC for new controls, new additions to the C++ compiler (which were already approved for C++0x), new deployment model, and others. In this post I will talk about the new build system and multi-targeting.

In order to show the changes I will create two simple projects, one in Visual Studio 2008, called Wordpad 2008, and one in Visual Studio 2010, called Wordpad 2010. These would be simple MFC single document applications. The image bellow shows the two solutions opened in Solution Explorer.

As you can see both versions contain the same solutions file (only the suffix in the name differs). The next image shows the files on disk, in comparison for the two solutions.

MS-Build System

The first thing to notice (though it might not be the obvious) is that the project file extension was modified. In Visual Studio 2008 it is called .vcproj, but in Visual Studio 2010 is called .vcxproj. Not only the extension changed, but also the content of the file. This is because in Visual Studio 2010, Visual C++ build system was changed from VCBuild to MSBuild. This build engine was already used for the languages targeting the .NET framework.

MSBuild uses XML project files, and the most important elements of a project are:

  • Items: units of input into the build system, grouped into item collections, which can be used as parameters to the tasks, using the syntax @(ItemCollectionName). Examples of items from the Wordpad2010 project:
      < ItemGroup >
        < ClInclude Include="MainFrm.h" / >
        < ClInclude Include="Resource.h" / >
        < ClInclude Include="stdafx.h" / >
        < ClInclude Include="targetver.h" / >
        < ClInclude Include="Wordpad2010.h" / >
        < ClInclude Include="Wordpad2010Doc.h" / >
        < ClInclude Include="Wordpad2010View.h" / >
      < /ItemGroup >
    
  • Properties: pairs of key/value used to configure the builds. The value of a property can be changed after it was defined. They can be referred in the project file using the syntax $(PropertyName). Examples of properties from the Wordpad2010 project.
      < PropertyGroup Label="Globals" >
        < ProjectGuid >{1E7DC2AA-8CAC-44A8-98F6-DE69249AD30C}< /ProjectGuid >
        < RootNamespace >Wordpad2010< /RootNamespace >
        < Keyword >MFCProj< /Keyword >
      < /PropertyGroup >
    
  • Tasks: reusable units of executable code used to perform builds. Example of tasks can be compiling input files, linking, running external tools. Tasks can be reused in different projects.
  • Targets: represent groupings of tasks in a particular order and expose parts of the project file as entry points into the build system.

You can get a deeper overview on the MSBuild engine here.

Another thing to notice is the presence of a file called Wordpad2010.vcxproj.filters. This file defines the solution explorer tree with the files contained in the project. This used to be a part of the file project, but in Visual Studio 2010 it was moved into a separate file. The reason is to keep the project file only for the build, not for the organization of the project.

The user specific settings used to be stored in a file called ProjectName.vcproj.fullyqualifiedusername.user. Now there is a new file called ProjectName.vcxproj.user.

You can read more about these changes in MSDN.

Multi-targeting

Visual Studio 2008 came to support for multi-targeting of the .NET framework, not only for C# and VB.NET, but also for C++/CLI. In addition to that, Visual Studio 2010 comes with support for native multi-targeting.

The managed multi-targeting allows to target different versions of the .NET framework for mixed-mode applications. By default the target version is the latest, 4.0. This can only be changed manually in the project file. The support for changing this from the IDE was not included in this version. Actually it was dropped, because in Visual Studio 2008 this was possible.

  < PropertyGroup Label="Globals" >
    < ProjectGuid >{AB3D9231-F8B6-4EAD-A15B-C792977AB26E}< /ProjectGuid >
    < RootNamespace >MixedModeDemo< /RootNamespace >
    < TargetFrameworkVersion >v3.5< /TargetFrameworkVersion >
    < Keyword >MFCDLLProj< /Keyword >
  < /PropertyGroup >

The native multi-targeting allows to use different versions of the tools and libraries to build (native) C++ projects. Of course, you must have the targeted toolset installed on your machine, in order to do that. You can define different configurations that target different versions of the toolsets. The targeted toolset can be changed from project’s properties page, General, Platform Toolset. The following image shows the available options on a machine with Visual Studio 2008 SP1 and Visual Studio 2010 installed side by side.

It is possible to target the previous version, 2008, 2005, 2003 and 2002. In theory it’s possible to target even VC6, but there is no support from Microsoft for that.

I suggest to read more about native multi-targeting here, and about managed multi-targeting, for mixed-mode applications, here.

In a next post I will talk about the changes to IntelliSense and browsing experience.

, , Hits for this post: 17584 .

Visual Studio 2010, currently in beta 1, replaces VCBuild with MSBuild as the build system, aligning C++ with the other languages that already used MSBuild. The VC++ team has already posted several articles on it’s blog about the new build system. Channel 9 has published recently a video with Bogdan Mihalcea, a developer in the VC++ build and system project team, talking about MSBuild. You can watch the video here.

, , , Hits for this post: 11237 .

Here is a list of new things in Visual Studio 2010 for unmanaged development.

Visual Studio IDE:

Visual C++

Visual Studio Tools:

Additional readings:

, , , , Hits for this post: 18361 .

I’ve recently discovered a new nice feature in the natice debugger of Visual Studio 2008: the visualization of bit flags.

Let’s take this enumeration for example. Notice that each constant is basically a bit flag.

enum Weekdays
{
   Monday = 1,
   Thuesday = 2,
   Wednesday = 4,
   Thursday = 8,
   Friday = 16,
   Saturday = 32,
   Sunday = 64
};

If we used those bitfields like this:

int _tmain(int argc, _TCHAR* argv[])
{
   Weekdays weeekend = (Weekdays)(Saturday | Sunday);

   return 0;
}

The debugger shows them like this:

Bit fields visualization in debugger.

However, if the constants are not bit flags, they are not shown. If you declare the enum like this:

enum Weekdays
{
   Monday,
   Thuesday,
   Wednesday,
   Thursday,
   Friday,
   Saturday,
   Sunday
};

you won’t get that in the debugger.

, , , Hits for this post: 16260 .