Can I use Visual Studio 2010's C++ compiler wi

2019-01-04 23:24发布

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?

8条回答
淡お忘
2楼-- · 2019-01-04 23:54

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.

查看更多
看我几分像从前
3楼-- · 2019-01-04 23:56

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:

.model flat

.data
__imp__EncodePointer@4 dd dummy
__imp__DecodePointer@4 dd dummy
EXTERNDEF __imp__EncodePointer@4 : DWORD
EXTERNDEF __imp__DecodePointer@4 : DWORD

.code
dummy proc
mov eax, [esp+4]
ret 4
dummy endp

end

And remember to set Linker->System->Minimum Required Version to 5.0 (default is 5.1) to run on Windows 2000.

查看更多
【Aperson】
4楼-- · 2019-01-04 23:58

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).

查看更多
淡お忘
5楼-- · 2019-01-05 00:00

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:

use32
format ms coff

section ".data" data
public __imp__DecodePointer@4
__imp__DecodePointer@4 dd dummy

public __imp__EncodePointer@4
__imp__EncodePointer@4 dd dummy

section ".text" code
dummy:
mov eax, [esp+4]
retn 4
查看更多
兄弟一词,经得起流年.
6楼-- · 2019-01-05 00:10

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 some typedefs 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 than std::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.

查看更多
Juvenile、少年°
7楼-- · 2019-01-05 00:10

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 and DecodePointer. (There should already be a #define for that.)

There are two other minor things you'll need to do:

  • Go to the Linker->Additional Library Directories setting and set 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.)
  • Change the subsystem version, in the PE header, to 5.00 (use the free CFF Explorer Suite if you don't have another tool handy for it).

That should allow your program to run on Windows 2000 as well as later versions.

查看更多
登录 后发表回答