I have an application that needs to operate on Windows 2000. I'd also like to use Visual Studio 2010 (mainly because of the change in the definition of the auto
keyword). However, I'm in a bit of a bind because I need the app to be able to operate on older OS's, namely:
- Windows 2000
- Windows XP RTM
- Windows XP SP1
Visual Studio 2010's runtime library depends on the EncodePointer / DecodePointer
API which was introduced in Windows XP SP2.
If using the alternate runtime library is possible, will this break code that relies on C++0x features added in VS2010, like std::regex
?
Option 1 - create a modified version of the 2010 runtime that redirects the problem API calls to a DLL that you supply. I don't know how easy or hard this would be - hopefully just a minor tweak to the symbol table, but it depends on the file format - and you're very likely to run into the reverse engineering clause of the license, of course.
Option 2 - Compare the exported symbols in two different versions of the runtime libs. If the symbols are the same, you have good odds of compatibility - though no guarantees. Its even possible that the lib file formats are different.
Option 3 - Check whether you can get access to runtime sources through the MSDN or similar, specifically in order to create a patched version.
Option 4 - Check whether you can use the 2010 compiler, but an older linker, perhaps configured in your solutions as a custom build step. Again, this depends on whether the obj and lib files are the same file format - but you may be able to write a small utility to patch simple differences like version numbers in a header. The older linker should have no problem linking in the older runtime - assuming the objs from the new compiler are compatible with it.
Option 5 - build DLLs in 2010 that don't need their own runtime, but which are loaded and hosted by an application built using the older compiler. Achieving the "no runtime" requirement for your DLLs may mean a lot of your libraries must be built in the hosting application, of course, and you may need to provide your own interfaces (via the host application) to library functions you need to work with - especially memory allocation stuff.
Options worth checking, but I'm sure you already thought of them all - sorry I have no idea whether any of them will work - or whether they'll almost work but cause intermittent problems.
As Visual Studio comes with support for MASM (see project properties -> Build Customizations...) the following translation of snemarch's code to MASM might be useful:
And remember to set Linker->System->Minimum Required Version to 5.0 (default is 5.1) to run on Windows 2000.
This would be a lot easier if you're allowed to use a DLL. Basically, write an EXE that requires no C runtime functions at all, by using the linker /ENTRYPOINT function. Once you've tested that your basic prerequisites are met, and reported any problems to the user via only Windows-provided APIs available on all target OSes (i.e. MessageBox), then call LoadLibrary to kick off the DLL that contains the bulk of your logic. That DLL can use the VS2010 runtime as usual. You can even avoid deploying two separate files by decompressing the DLL from a resource contained within your main .EXE at startup. (You can do this entirely within memory without writing the .DLL to disk, but not if you want to take advantage of the Windows PE loader to fixup all your imports).
Suma's solution looked pretty promising, but it doesn't work: the
__imp__*@4
symbols need to be pointers to functions, rather than the functions themselves. Unfortunately, I don't know how to make Visual C++ spit out a pointer with that kind of name generation... (well,__declspec(naked)
combined with__stdcall
does the trick, but then I don't know how to emit a pointer).If using an assembler at build-time is OK, the solution is pretty trivial - assemble the following code with FASM and link against the produced object file, and presto - no EncodePointer/DecodePointer references in the exe:
The very simplest solution is just to set the Platform Toolset in project settings in VS2010 to v900, which will use the Visual Studio 2008 libraries and compiler. This also means you lose C++0x features like
auto
, but to be honest, working around that with sometypedef
s is probably easier than building your own version of the CRT or other more complicated solutions. Alternatively, just use VS2008! I don't know if there are other C++0x features that are critical to your application though, you didn't mention - other thanstd::regex
, which I think is still in the v900 toolset under the technical report 1 namespace (std::tr1::regex
).Just from the impression I get, I would predict the inconvenience of getting the VS2010 libraries to run on XP SP1 is greater than the convenience of C++0x features, so overall it wouldn't be worth it.
The usual work-around for this problem is to build your own custom version of the CRT. There are instructions for it here. You'll just need to edit the code to ignore
EncodePointer
andDecodePointer
. (There should already be a#define
for that.)There are two other minor things you'll need to do:
C:\Microsoft Visual Studio 9.0\VC\lib
as the first path to search. (I'm assuming you used the default install directory, otherwise change as appropriate.)That should allow your program to run on Windows 2000 as well as later versions.