My questions are:
Is it possible to link to VS2008 generated DLLs using VS2010?
If not, why does it seem to be possible to link to static libraries generated by VS2008.
I see that VS2010 now has a Platform Toolset option. But will that let people set it to v90 instead of v100 even though they don't have VS2008 installed?
Even though I use the /Z7 compiler switch, why do I still need to have a .pdb to debug DLLs.
The Details
I can use Visual Studio 2010 to link to my Leptonica C static libraries generated by Visual Studio 2008 without any problems. (See the References section below for details on how I build Leptonica and link to it.)
However, when I try to link the same program (leptonlib-1.67\prog\ioformats_reg.c) with my VS2008 generated DLL version of Leptonica the program crashes. Debugging, I can see that the problem is that ioformats_reg.c does this:
fp = fopen(filename, "rb"); /* in ioformats_reg.c */
and soon thereafter, in the leptonlib.dll the following is done which crashes:
rewind(fp); /* in leptonlib.dll */
How to link with the correct C Run-Time (CRT) library says:
A reusable library and all of its users should use the same CRT library types and therefore the same compiler switch...
If you do choose to mix CRT libraries, remember that you have two separate copies of the CRT, with separate and distinct states, so you must be careful about what you try to do across a CRT-boundary. There are many ways to get into trouble with two CRTs. Here are just a few:
- There are two separate heaps. You cannot allocate (explicitly with new, malloc, or so on -- or implicitly with strdup, strstreambuf::str, or so on), and then pass the pointer across a CRT-boundary to be freed.
- You cannot pass a FILE* or file handle across a CRT-boundary and expect the "stdio low-level IO" to work.
- You cannot set the locale in one and expect the other's locale to be set.
Beginning with Visual C++ 4.0, the linker will issue a warning (LNK4098) if a resulting module attempts to combine more than one copy of the CRT library. For more information, search the Help file for LNK4098.
But I do not get any LNK4098 error messages from the VS2010 linker.
Leptonica uses fopen(), rewind(), fclose(), etc. which the documentation categorizes as Stream I/O not "low-level IO", but those do pass around FILE ptrs. I suppose this is what Microsoft means when they say "stdio low-level IO".
/MD, /MT, /LD (Use Run-Time Library) says:
All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD).
It doesn't say that all modules have to be compiled by the same version of the compiler. I do use /MD (or /MDd) consistently and correctly for all my modules.
When using DLLs it appears that the DLLs not only have to use the same /MD switch, but they also have to be compiled by VS2010?
My test case seems to indicate that linking with static libraries generated by VS2008 works, but maybe I just got lucky? Why does linking to VS2008 generated static libraries work, while linking to a VS2008 generated DLL doesn't when using VS2010?
Does this mean that I need to ship separate DLLs for use by VS2008 and VS2010 users?
And what about the new Platform Toolset option? Can VS2010 users change that to v900 even though they don't have VS2008? If so, then I could just tell people to change that setting for my Leptonlib-1.67 project.
Finally, I use the /Z7 switch when creating my libraries. The documentation at /Z7, /Zi, /ZI (Debug Information Format) states:
/Z7
Produces an .obj file containing full symbolic debugging information for use with the debugger. The symbolic debugging information includes the names and types of variables, as well as functions and line numbers. No .pdb file is produced.
For distributors of third-party libraries, there is an advantage to not having a .pdb file. However, the .obj files for the precompiled headers are necessary during the link phase, and debugging. If there is only type information (and no code) in the .pch object files, you will also have to compile with /Yl (Inject PCH Reference for Debug Library).
I am not using any precompiled headers. However, it's only when I have the .pdb available that I can debug my Leptonica DLLs. Also even though it says "No .pdb file is produced." a .pdb is in fact generated with my current project settings. Does having /PDB in my linker options somehow override having specified /Z7 while compiling?
Edit: Also I should mention that I am able to debug the static library version of Leptonica even without any PDB.
References
Leptonica is the open-source C Image Processing Library by Dan Bloomberg available at http://www.leptonica.com. I provide the instructions for building Leptonica using VS2008/VS2010 and also provide windows binaries.
See http://leptonica.com/vs2008doc/building-leptonlib.html and http://leptonica.com/vs2008doc/building-image-libraries.html for details on how I build the Leptonica libraries. http://www.leptonica.org/vs2008doc/building-prog-dir.html discusses how I link ioformats_reg.
My Leptonica VS2008 Solution is available at http://www.leptonica.com/source/vs2008-1.67.zip. My binary libraries are in the zip file at http://leptonica.com/source/leptonica-1.67-win32-lib-include-dirs.zip. The Leptonica sources are at http://www.leptonica.com/source/leptonlib-1.67.tar.gz