Building .dll for lower version of visual studio - c++

I'm using Visual Studio 2010 to build my DLL library.
And, other programmer who's using Visual Studio 2005 wants to use my DLL library. He can compile with my dll, but, when running his application, it just crashes with bad_alloc exception. I assume that's because of different CRT version.
When building my DLL library, I tried both dynamic linking of CRT(/MD) and static linking of CRT(/MT), but both failed.
So, can't I make DLL library that can be used by lower version of visual studio? If not, how I can I do that?

As far as I know you have to use only primitive types dll interface. it's because even in a same compiler memmory layout changes by only changeing compile flags, think of what would happen by changing compiler. and that could lead to a largescale undifined behavior.
and use the following format for your function interfaces:
extern "C" __declspec(dllexport) void doSomething(int input);

You can only export abstract base classes (containing at least one pure virtual function) with no data members for binary compatibility, I guess that was behind the question about your dll prototype. Here http://chadaustin.me/cppinterface.html is a good discussion on the issue.

Most easiest solution: give the other programmer the source code of your DLL and let him compile the DLL by himself against the old CRT. If that's not suitable (because you don't want to give the source code out of your hands, or your DLL does not compile with VC++ 2005), either you have to get a VC++ 2005 compiler, or the other one VC++ 2010.

If you have VS2005 installed on you machine, you can use the VS2010 new Platform Toolset feature to use the VS2005 compiler.
Its under Project Properties->General->Platform Toolset. VS100 is vs2010, VS90 goes for 2008 and (i think) VS80 is what you need (for 2005...).
AFAIK, trying to use different toolset built DLL will be harder (though possible, as you don't link with it).
Cheers

Most likely, you are using things (like C++ containers or types) that have changed between versions of VC++ compiler implementations, and passing these across DLL boundaries between DLLs built with different VC++ versions is likely to fail.
You need to build the DLL with that specific compiler (VC++ 8.0 for VS2005, VC++ 9.0 for 2008, VC++ 10.0 for 2010...) in order for the other programmer to use it. That, or he has to upgrade his Visual Studio to use the same version as you.

This is a fairly old problem and this is one of the reasons for COM. I would suggest you do the following -
Create an abstract base class and (aka interface) (say IExportedFunctionality) that exposes the methods that your currently exported class (say CExportedClass) offers and has a virtual destructor.
Dont export CExportedClass any more.
Derive CExportedClass from IExportedFunctionality and ensure all the methods are implemented.
Export 2 functions from your Dll named
a. GetExportedClass which returns a pointer to a new instance of CExportedClass upcast to IExportedFunctionality*.
b. FreeExportedClass which accepts a IExportedFunctionality* and deletes it.
Now all you need to do is provide the header file with the declaration of IExportedFunctionality. You can even do away with the lib file as your users can make use of LoadLibrary and GetProcAddress to call GetExportedClass and FreeExportedClass.
Note: IExportedFunctionality should have
Only pure virtual functions - since IExportedFunctionality is an interface not implementation.
Pure virtual destructor - so that doing a delete on a IExportedFunctionality* will translate into a call to CExportedClass's destructor
Do not have ANY data members in IExportedFunctionality (As user383522 pointed out binary layout of the class can vary across compilers and under different byte alignments)

Related

C++ | Windows - Passing STL objects to DLL

I have seen some very well questions but I decided I would ask my own because they weren't quite what I wanted to know.
There was a lot of talk about how you shouldn't pass std::string into a function (from a DLL) because everything has to match CRT, Platform version, etc but can you safely pass a const *char to a function and then inside of the .dll use std::string's?
The reason I ask is because I recently discovered how amazingly useful C++ strings are and I want to use them with my .DLL but I have discovered they are unsafe to use with .dll's because of runtime templates and such.
So my question is mainly, is there a "safe" way to use std::string in a .dll?
It's entirely safe to use it internally.
And don't worry too much about using a std::string across DLL boundaries either. You can't use it in a public interface, but when you ship a DLL with your own program you control both sides. It's quite common to have both the DLL and the EXE in two Visual Studio projects within one VS solution. That ensures they're built with the same platform version etc.
Feel free to use std::string in DLL interface. But you should make sure that DLL and Application must be built with the same std library to avoid std::string boundary problem.
There is no ABI documented, so technically, it can change with the compiler version, and can depend on compiler settings.
You should be on the safe side if caller and DLL are built by the same version of Visual C++.
However this means: you cannot use it in a public interface, and you are giving up compatibility between versions (say, running an oder EXE with a newer DLL - after upgrading your compiler).

Allocate C++ object across MSVCRT versions

I have VS2010 and i need to build application.
Also i have .dll with .lib and .h built with VS2005.
This library depend on log4cxx.dll (i built 2010 and downloaded 2005 binary).
When i call library interface method which return reference to built object it throw AV exception. I can't build my app with another version and i've already tried change to Multithreaded Debug my app type.
It is likely that object you are getting has another memory layout.
If you are passing c++ object across runtime boundaries you should be sure that recieving object has the same layout. For example if VS2005 compiler have reordered it fields for optimization and VS2010 done it other way. Or one of classes you used (eg std::string) changed between versions. Read how objects are returned from COM methods.
There is also problem with object allocation in one runtime and deallocation in another...
As a solution you can try installing VS2005, but there is no guarantees that you end up same

Use VC++ 2010 runtime libraries in VC++ 2008 project

I work on the optimization algorithm so the performance really matters. The algorithm is about 8 times faster when compiled in VS 2010 compared to VS 2008. Googling shows that it is not my fault (see e.g. https://stackoverflow.com/a/5560184/890355). The problem is that the final project must be built under VS 2008.
The solution I tend to is to built my algorithm as DLL in VS 2010 and then link it to the main project. Is it possible to use VC++ 2010 run-time libraries with my DLL under VS 2008? If so, what is the least painful way to do it?
Any other ideas?
Thanks.
The runtimes are not an issue. Nothing stops you from linking your DLL against the VC2010 runtime and then using that DLL in other projects. It doesn't matter if those projects are built using Visual C++ 2008 or any other language.
The tricky part is designing the DLL interface. Simply exporting some C++ classes is risky since it exposes you to incompatibilities between the different compilers. I think your best bet would be to either expose a C-style interface or use COM. I think COM is the best approach, but if you're unfamiliar with the technology, then a C-style interface will work fine. (COM could also be over-kill if the interface is simple.)
If you ask for any other way to combine 2008 and 2010 libraries in one executable other than moving 2010 part outside into a DLL, than the answer is probably "there is no other easy way to achieve this".
But if you don't want to "VC++ 2010 run-time libraries ... under VS 2008" (that is building against 2010 libraries in old 2008 IDE), but "use a 2010-compiled DLL in your 2008-compiled program", it is perfectly possible.
The easiest way, as we do it in our projects, is to build (both .exe and DLL) against statically linked standard libraries (MFC, if you use it) and then use LoadLibrary in your .exe to load the DLL. In the DLL you can export (_declspec (dllexport)) a function (preferably inside extern "C" {} guards) and use it in the .exe through GetProcAddress.
Static linkage and explicit loading save you from a lot of inconsistency bugs caused by different runtimes.
If you are worried about DLL loading and function calling costs, you can try to make these calls as rare as possible (maybe by moving not only the algorithm, but also some more high-level logics into the DLL). See this issie too.
And you can build all your code in one IDE (2010) using native multitargeting (however you will still need to build you main app and DLL separately against v9 and v10 libraries respectively).
You can if you're careful, and the MS documentation provides some hints. I have answered this question before here:
Wondering if the lower version of visual studio can use the dll built using higher version of visual studio?

MS vs Non-MS C++ compiler compatibility

Thinking of using MinGW as an alternative to VC++ on Windows, but am worried about compatibility issues. I am thinking in terms of behaviour, performance on Windows (any chance a MinGW compiled EXE might act up). Also, in terms of calling the Windows API, third-party DLLs, generatic and using compatible static libraries, and other issues encountered with mixing parts of the same application with the two compilers.
First, MinGW is not a compiler, but an environment, it is bundled with gcc.
If you think of using gcc to compile code and have it call the Windows API, it's okay as it's C; but for C++ DLLs generated by MSVC, you might have a harsh wake-up call.
The main issue is that in C++, each compiler has its own name mangling (or more generally ABI) and its own Standard library. You cannot mix two different ABI or two different Standard Libraries. End of the story.
Clang has a specific MSVC compatibility mode, allowing it to accept code that MSVC accepts and to emit code that is binary compatible with code compiled with MSVC. Indeed, it is even officially supported in Visual Studio.
Obviously, you could also simply do the cross-DLL communication in C to circumvent most issues.
EDIT: Kerrek's clarification.
It is possible to compile a large amount of C++ code developed for VC++ with the MinGW toolchain; however, the ease with which you complete this task depends significantly on how C++-standards-compliant the code is.
If the C++ code utilizes VC++ extensions, such as __uuidof, then you will need to rewrite these portions.
You won't be able to compile ATL & MFC code with MinGW because the ATL & MFC headers utilize a number of VC++ extensions and depend on VC++-specific behaviors:
try-except Statements
__uuidof
throw(...)
Calling a function without forward-declaring it.
__declspec(nothrow)
...
You won't be able to use VC++-generated LIB files, so you can't use MinGW's linker, ld, to link static libraries without recompiling the library code as a MinGW A archive.
You can link with closed-source DLLs; however, you will need to export the symbols of the DLL as a DEF file and use dlltool to make the corresponding A archive (similar to the VC++ LIB file for each DLL).
MinGW's inclusion of the w32api project basically means that code using the Windows C API will compile just fine, although some of the newer functions may not be immediately available. For example, a few months ago I was having trouble compiling code that used some of the "secure" functions (the ones with the _s suffix), but I got around this problem by exporting the symbols of the DLL as a DEF, preparing an up-to-date A archive, and writing forward declarations.
In some cases, you will need to adjust the arguments to the MinGW preprocessor, cpp, to make sure that all header files are properly included and that certain macros are predefined correctly.
What I recommend is just trying it. You will definitely encounter problems, but you can usually find a solution to each by searching on the Internet or asking someone. If for no other reason, you should try it to learn more about C++, differences between compilers, and what standards-compliant code is.

Error linking with 3rd party static library built with previous version of Visual Studio

I am working on a project that links to a 3rd party static library (herin refered to as EXTERNALLIB). In Visual Studio 2005 I was able to link to EXTERNALLIB and create a usable executable. Now we are using Visual Studio 2008 and I am receiving the following error:
fatal error C1047: The object or library file EXTERNALLIB was created with an older compiler than other objects; rebuild old objects and libraries.
Is there a way for me to tell the compiler to correctly link to EXTERNALLIB? I believe the problem may be related to specific calling conventions (__stdcall, __cdecl, __clrcall, __thiscall). Can I indicate in the new program the correct calling convention for the old library? Is there specific feedback that I can give to our vendor (such as using APIENTRY in the header files) such that this problem does not occur with future compiler upgrades?
The code is writen in C++. I do not have access to the code for EXTERNALLIB and thus I am unable to rebuild it myself.
You problem is likely to result from "the code is written in C++". The ABI for C++ linkage is essentially completely unspecified by any standard, and is notoriously changeable from compiler to compiler. I suspect that VS is trying to tell you that the ABI has changed again, and that as a result it cannot link directly to the library.
This problem is often exacerbated by wanting to implement C++ objects in a DLL, but luckily you don't have that problem here.
One approach to a solution that should work is to skin the published API of EXTERNALLIB with a C-callable adaptor, and to link that whole thing into a DLL. Build the skin with the older VS version (at worst, the free edition should still be findable). Make sure that only extern "C" functions are exposed. Especially make sure that no global objects are exposed from the DLL (although they may need to exist within your skin).
The best answer is go back to the supplier of EXTERNALLIB and politely report the failure to link with the current VS as a bug and request a rebuilt version.