Porting C++ Code to 64-bits

Link. October 17, 2008. Comments [0]. Posted in: C++

Back in the good old days I spent far more time writing C++ code than other things (well, there was no C# back then!). In those days, the initial support for 64-bit compilation was added to the Platform SDK (now the Windows SDK… again!).

At that time I couldn’t even dream of getting access to a 64-bit machine, and only very recently was able to get one. However, I still thought that learning to write portable 32/64-bit code the way the SDK prescribed was a good idea and so got used to it a bit.

It wasn’t actually all that hard. A big chunk of it was just being careful about integral/pointer conversions, using the new SDK data types like INT_PTR, ULONG_PTR and friends, and being wary of memory alignment issues. Just that would take you a long way on the right path. It was particularly easy when you were starting from scratch.

Since I do a lot less C++ these days, I had put a lot of that knowledge in the back of my head. Recently, however, I started looking into making some initial changes to an existing C++ code base to start cleaning up stuff for porting to 64-bits.

On the plus side, the Visual C++ compiler gives you a lot of really good warnings on problematic spots, either by actually compiling with the 64-bit compiler or by using the old /Wp64 switch on the regular 32-bit one (though the switch is deprecated now). Documentation on the Windows SDK about 64-bit porting issues is also fairly good.

On the negative side, it can still be a bit of a drag; it’s a lot more challenging to modify an existing, complex code base than starting writing portable code from scratch. Still, it’s been an interesting experience ;-).

Console2 and x64

Link. September 18, 2008. Comments [6]. Posted in: C++ | Tools

I recently mentioned that version 2.00b140 of the great Console utility had come out. Eddie Velasquez commented on that post that, unfortunately, Console didn't work correctly on Windows x64.

I had the opportunity to verify this during the last week. Console2 runs, but all text drawn on the console is invisible, which makes it a bit hard to read :-). I looked around the web, and although a few people mentioned seeing the same problem, no one offered any solutions. So I decided to take a look.

I installed Visual C++ 2008 on my x64 machine, downloaded the Console2 source code package and went hunting around for all dependencies needed to actually build it, which took a couple of hours. Off the top of my head, you need:

After a bit of tweaking the project files, I was able to build an x86 version of the code and started looking around the code to see where the problem might be. I checked a few things, like:

  • Was it possible that it was interacting incorrectly with the underlying system console and not picking up the text colors? Nope. Debugger showed me it was indeed picking up the right color for each character drawn.
  • Was it possible that it was mapping colors incorrectly? nope, not that either.
  • Was it possible it was drawing the text in the wrong locations? Didn't seem to be that either, as you could even copy paste the text from Console correctly, and the caret seemed to be at the right location either.
  • Could the off-screen surfaces be somehow invalid? Nope, a few calls to GetDeviceCaps() showed it had all the correct number of planes and bits per pixel that you'd expect.

After a few hours of tinkering, I was able to narrow it down to one issue: the use of the AlphaBlend() function when blitting between the off-screen and on-screen surfaces. In fact, I'm fairly confident that the issue Console2 is running into is the same one described on this newsgroup post. Unfortunately, that didn't seem to point to a good workaround for the issue.

Now, my GDI programming isn't very fresh on my mind, and frankly, I didn't want to sit around for a long time trying to get this fixed. However, I was able to make a quick change to the code that would make it work. The changes are setting up the BlendFunction for AlphaBlend slightly different.

The change I did was around line 1979, changing the setup before AlphaBlend like this:

blendFn.BlendOp               = AC_SRC_OVER;
blendFn.BlendFlags            = 0;
blendFn.SourceConstantAlpha   = 255;
blendFn.AlphaFormat           = AC_SRC_OVER;

Now, to be honest, this is just a hack, but it does the trick for now, using ClearType for font rendering and even alpha transparency on the entire window. I was not able (at least not in my quick look at the code) to fix the code path that gets executed when you're using an image as the console background, since that actually does require full alpha-blending to render the right output.

So it's not a great fix, but it means I can use Console2 on my x64 box now, which is good enough for me at this point. YMMV.

Using Visual C++ 6.0

Link. June 15, 2007. Comments [0]. Posted in: C++ | Development

I've been spending most of my time this week back in the unmanaged world, writing C++ code again in good old Visual C++ 6.0. To make it even more fun, this was OLE DB with ATL. To be honest, took me a couple of hours to get the hang of it again, but after that my C++ started to come back more easily.

I did finally remember one of the reasons I moved off C++ to the managed code: Strings. Man, dealing with strings in C++ is just painful, even with CString, CComBSTR, _bstr_t, std:string and std:wstring at your disposal. Or maybe, that's just another reason it can be a pain in the neck. Anyway, if you find yourself writing OLE DB code again, the RowsetViewer tool in the MDAC SDK is a godsend :-).

One thing that I can say in favor of Visual C++ 6.0: The thing is freaking fast compared to Visual Studio 2005. However, I didn't remember there was no obvious way to change the font and font size, so using VC++ 6.0 on a hi-res screen isn't a particularly nice experience.

Martyn Lovell on the Secure CRT

Link. April 28, 2006. Comments [0]. Posted in: C++

There's a video posted over on Channel 9 featuring Martyn Lovell from the Visual C++ team talking about the Secure CRT. For those of you still using C++ this might be interesting...

C++/CLI with WSE 3.0 Sample

Link. March 27, 2006. Comments [1]. Posted in: .NET | Web Services | C++

I've just uploaded a new sample showing the use of WSE 3.0 from C++/CLI. The sample consists of a C++/CLI ASMX Service which allows users to upload/download files, query file information and list available files, and a simple C++/CLI Winforms client.

SimpleFileServer_Client.png The sample illustrates the following features:

  • UsernameToken-based authentication
  • Use of a simple UsernameTokenManager class for authentication (password==username)
  • MTOM use for upload/download of files between client and server

Some useful tips when creating WSE applications with C++/CLI are:

  1. To create the client-side proxy, don't use the Add Web Reference wizard in Visual Studio, instead use WSDL.EXE with the /language:CPP option and then add the generated .H file into your project. This is because you'll want to modify the generated code (to have the proxy class derive from WebServicesClientProtocol instead of the usual HttpClientProtocol), and the Add Web Reference wizard is not good for that: It actually compiles code to a separate DLL, and it also will re-generate the proxy code from the WSDL when you do a Rebuild-All.
  2. You can use policy files for both client- and server-side security policy configuration; the sample uses a very simple policy requesting UsernameToken based authentication. What you cannot do is use the WSE Settings wizard to edit the policy file directly. However, you can easily start with basic policy by copy-pasting it from the WSE documentation (watch out, errors abound!) or from one created in a sample C# project.
  3. Make sure you manually add a reference to Microsoft.Web.Services3.dll to your C++/CLI projects. You will also need to manually modify the Web.Config and app.config files to include the relevant WSE3 sections to them. For example, here's the web.config lines added for the service:

   <configSections>

      <section name="microsoft.web.services3"

         type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

   </configSections>

   ...

   <system.web>

      ...

      <webServices>

         <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

      </webServices>

   </system.web>

 

   <microsoft.web.services3>

      <messaging>

         <mtom serverMode="always" />

      </messaging>

      <security>

         <securityTokenManager>

            <add localName="UsernameToken"

                 type="SimpleFileServer.CustomUsernameTokenManager, SimpleFileServer"

                 namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>

         </securityTokenManager>

      </security>

      <policy fileName="policy.config"/>

   </microsoft.web.services3>

 

Hope someone finds this useful!

 

Syndicate

About

Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...

tomasrestrepo @ twitter My Flickr photostream My saved links on delicious My Technorati Profile

email: tomas@winterdom.com
msn: tomasr@passport.com

View my profile on LinkedIn

MVP logo

Ads


Categories

Statistics

Total Posts: 1051
This Year: 2
This Month: 2
This Week: 1
Comments: 827

Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.2.8279.16125

Sign In