Can I use a Visual Studio 6 compiled C++ static library in Visual Studio 2008? - visual-studio

Is it possible to use a C++ static library (.lib) compiled using Visual Studio 6 in Visual Studio 2008?

It really depends. Does the lib expose only 'extern "C"' functions where memory is either managed by straight Win32 methods (CoTaskMemAlloc, etc) or the caller never frees memory allocated by the callee or vice-versa? Do you only rely on basic libraries that haven't changed much since VS 6? If so, you should be fine.
There are 2 basic things to watch for. Changes to global variables used by 3rd-party libraries, and changes to the structure of structs, classes, etc defined by those 3rd-party libraries. For example, the CRT memory allocator has probably changed its hidden allocation management structures between the 2 versions, so having one version of the library allocate a piece of memory and having another free it will probably cause a crash.
As another example, if you expose C++ classes through the interface and they rely on MS runtime libraries like MFC, there's a chance that the class layout has changed between VS 6 and VS 2008. That means that accessing a member/field on the class could go to the wrong thing and cause unpredictable results. You're probably hosed if the .lib uses MFC in any capacity. MFC defines and internally uses tons of globals, and any access to MFC globals by the operations in the .lib could cause failures if the MFC infrastructure has changed in the hosting environment (it has changed a lot since VS 6, BTW).
I haven't explored exactly what changes were made in the MFC headers, but I've seen unpredictable behavior between MFC/ATL-based class binaries compiled in different VS versions.
On top of those issues, there's a risk for functions like strtok() that rely on static global variables defined in the run-time libraries. I'm not sure, but I'm concerned those static variables may not get initialized properly if you use a client expecting the single-threaded CRT on a thread created on the multi-threaded CRT. Look at the documentation for _beginthread() for more info.

I shouldn't think why not - as long as you keep the usual CRT memory boundaries (ie if you allocate memory inside a library function, always free it from inside the library - by calling a function in the lib to do the freeing).
this approach works fine for dlls compiled with all kinds of compilers, statically linked libs should be ok too.

Yes. There should be no issues with this at all. As gbjbaanb mentioned, you need to mind your memory, but VS2008 will still work with it. As long as you are not trying to mix CLR, (managed) code with it. I'd recommend against that if at all possible. But, if you are talking about raw C or C++ code, sure, it'll work.
What exactly are you planning on using? (What is in this library?) Have you tried it already, but are having issues, or are you just checking before you waste a bunch of time trying to get something to work that just wont?

Sure it'll work.
Are you asking where in VS2008 to code the references?
If so, go to proj props -> Linker -> Input on Configuration properties on the property pages. Look for "additional dependencies" and code the .LIB there.
Go to proj props -> Linker -> General and code the libs path in "Additional Library Directories".
That should do it!!

There are cases were the answer is no, when we moved from VS6 to VS2k5 we had to rebuild all our libraries, as the memory model had changed, and the CRT functions where different.

There were a handful of breaking changes between VC6, VS2003, VS2005 and VS2008. Visual C++ (in VS2005) stopped support for single-threaded, statically linked CRT library. Some breaking changes enumerated here and here. Those changes will impact your use of VC6 built libs in later versions.

Related

Visual Studio 2015 libc is not backwards compatible

The definition of mbstate_t has changed from:
typedef int mbstate_t;
to
typedef struct _Mbstatet
{ // state of a multibyte translation
unsigned long _Wchar;
unsigned short _Byte, _State;
} _Mbstatet;
typedef _Mbstatet mbstate_t;
This is not backwards compatible and seems to imply all components of a Windows desktop application will need recompiling with VS 2015 if I am to use VS 2015. Obviously "all" is too strong here, only components using mbstate_t are affected. However, that's still not a good situation.
Are we expected to recompile if we migrate to VS 2015? Am I missing something here which means this isn't an issue?
Given that this struct has changed I have bigger concerns that there may be other breaking changes between VS 2013 and 2015. Is there a list of these anywhere?
Note:
I've already asked this question on MSDN but my gut tells me more eyes will be on it on Stack Overflow: https://social.msdn.microsoft.com/Forums/vstudio/en-US/8e50f348-0b6d-442c-8a1e-b1b8a4288fbc/mbstatet-is-not-backwards-compatible-between-vs-2015-and-vs-2013?forum=vcgeneral#8e50f348-0b6d-442c-8a1e-b1b8a4288fbc
To answer the question. Yes, you are expected to recompile everything if you wish to update to newer versions of Visual Studio. MS reserve the right to change any part of toolchain and libraries. There are clear examples of C headers and C++ headers changing. Plenty of other things could change as well which would make binary compatibility between versions difficult or impossible.
Some discussion / opinion
In my mind it is not 100% obvious that you'd need to recompile everything when updating to a newer version of the toolchain. Forcing a user to recompile everything to update to a new toolchain can be quite burdensome. In large projects you may be dependent on a lot of 3rd party code which you have no way of recompiling. Many SDK expend a lot of energy in ensuring backwards compatibilty so that users don't have to do this.
Interestingly the linker makes no effort to disallow linking against libraries built with older versions of the toolchain. It doesn't even warn! This behaviour might imply that it's acceptable to link old libraries with new code.
Anyway, I could waffle about this all day. One thing I wanted to point out is that if you know what you're doing then it is possible to link binaries built with older versions of VS against newer versions. You have to be very clear about what declarations (effectively your header files) your code was built against and know that these declarations either haven't changed or they have changed in a way that doesn't cause runtime errors. You also have to be sure that the compiler hasn't changed the way it handles builtins/intrinsics etc. in a sufficient way to hurt you. For example, the use of a try/catch block with MSVC will cause code to be automatically generated to handle exceptions. This will lead to implicit calls to functions provided by the runtime libs. That could easily change version to version and you could be left with undefined symbols or unexpected behaviour.
Proceed with caution :)
It used to be that Visual C++ actually did try to maintain C runtime library backwards compatibility at the object file (and thus static library) level. Opaque types like mbstate_t might change their internal representation, but they wouldn't change their size. This allowed an object file compiled with older versions of the CRT headers to work when linked with a newer version of the CRT.
(Note that this doesn't apply when CRT objects are passed across DLL boundaries. Multiple CRTs in the same program, whether statically or dynamically linked, are not compatible.)
This mostly only applied to C code however. The Standard C++ Library was not backwards compatible at all, and there are actually linker checks to enforce this. (Though not if the out of date object files were compiled with Visual Studio 2008 or earlier.) Also the C++ ABI is subject to change between major releases, so potentially the layout of C++ objects can change.
However as you've noticed with Visual Studio 2015, the C runtime library is no longer backwards compatible. The CRT went through a major refactoring and many things changed. Most of it is no even longer part of Visual Studio, and instead is now a part of the Windows operating system. As you've also noticed, there's no error or warning when you to try to link older binaries with the new CRT. As the old CRT didn't include any version symbols in the compiled object files, so there's way it can know if they were compiled using the old CRT headers.

How to use VS2010 built dlls in VS2008

In my work we have VS2008.
Some partners in the project I work, use VS2010 (can't use VS2008)
They have to build a dll based and I have to use that dll in my framework...
I managed to build the main app and link the dll's.
the app starts, and objects from the VS2010 dll's are created,
but the app crashes when i try to delete these objects...
Windows has triggered a breakpoint in app.exe. This may be due to a
corruption of the heap, which indicates a bug in app.exe or any of the
DLLs it has loaded.
Have you any ideas on how to fix this?
Your co-workers' DLLs are linked against VS2010's runtime library. Your code is linked against VS2008's runtime library.
When you call some function from the VS2010 dll to allocate a new object, it will be allocated on that library's heap. When you call "delete" on that object, VS2008's runtime library will try to free it from its own heap. Since they're different, you get that error.
If you're going to mix runtimes like that, you need the VS2010 dll to expose free()-style functions (not just C++ destructors) for each type. There are other things you should be very careful with when mixing runtime libraries like that, such as using STL containers, or any sort of "copy-on-write" objects. In general, it's easier to avoid it.
Object that was allocated in dll or in an exe should be deallocated in same place. You need to talk about that with your partners. For the goal may be used overloading of allocating and deallocating operators http://www.cprogramming.com/tutorial/operator_new.html

Microsoft visual C++ backwards compatibility

Consider a C++ API defined as a series of __options(declexport/import) classes.
Further, assume that the caller is never permitted to call the ordinary operator new(size_t) on these classes. Either a static factory method does the new-ing or there is a class-specific operator new. And ditto marks on the delete size as needed (frequently just a virtual destructor).
Now, if you compile and link a DLL and an IMPLIB of with the tools from VS2010, can you hand that implib and DLL to a user of VS2005 and expect it to work?
MFC is not involved here at all.
I'd be particularly grateful to any reference to any relatively formal Microsoft statement on the subject.
So long as the name mangling on the C++ API is identical (they are), and does not use STL-type specific parameters, such as basic_string or std::map, whose implementation may have changed between releases of the compiler (and they have), then it should just work.
Of course, you'll want to make sure you either compiled your DLL using /MT mode (static linked runtimes), or include the redistributables for VS2010 runtimes with your supplied libraries and link targets.
EDIT: Expanding on "don't pass in types that have version-specific implementations". A partial list is most easily found by looking at the output of the exports of MSVC100P.DLL.
cd %VS100COMNTOOLS%\..\VC\redist\x86\Microsoft.VC100.CRT
DUMPBIN /exports MSVCP100.DLL
The next issue will be header-only implementations of things like map or set which have changed under the hood between versions of the compiler.
This is why it's highly recommended that only scalar types be passed across boundaries between memory arenas. And thus, simple tests will pass, and be reliable.
You have not mentioned if you have used MFC to create the DLL's .If you have, regular DLL's should work , but I dont think extension shall work as the latter links to the MFC dlls .I am including links for your reference.
http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c4017
http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20385543.html
http://msdn.microsoft.com/en-us/library/26h8x9sy%28v=VS.100%29.aspx
EDIT
If its a normal DLL, there should not be any problem.Also depends on the linkage type.

Build static Library Using Visual C++ 2008, and Use it under Visual C++ 6

I was wondering any of you has successfully done that before?
If yes, is anything I need to pay attention to?
That idea is a non-starter.
The VC6 static library will need to link against the same CRT as the VC9 one in order to avoid multiply defined symbols, mismatching heap implementations and other nastiness. That won't be an easy task as the VC compilers make assumptions about the contents of the CRT.
The layout of structs and classes will differ between VC6 and VC9, even though the declarations may match exactly, the objects won't be compatible.
If you need to do this, your best bet would be to wrap the VC6 static library in a VC6 dynamic library that provides a c-style interface and access that from VC9.
I'd say no.
Why not just build it in VC6?

Which headers should I not use if I don't want my program to be linked with any of msvc*.dll's?

Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.

Resources